We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
之前看《深入理解es6》的笔记。。。
在ES6之前,在函数作用域中或者全局作用域中通过var关键字来声明变量,无论是在代码的哪个位置,这条声明语句都会提到最顶部来执行,这就是变量声明提升。
var
注意:只是声明提升,初始化并没有提升。
看一个例子:
function getStudent(name){ if(name){ var age=25; }else{ console.log("name不存在"); } console.log(age); //undefined }
如果按照预想的代码的执行顺序,当name有值时才会创建变量age,可是执行代码发现,即使不传入name,判断语句外的输出语句并没有报错,而是输出undefined。
name
age
undefined
这就是变量声明提升。
ES6前是没有块级作用域的,比如{}外可以访问内部的变量。
{}
function getStudent(name){ if(name){ let age=25; console.log(age); //25 }else{ console.log("name不存在"); } console.log(age); //age is not defined }
和上文一样的代码,只是将age的命名关键字从var改成了let,在执行getStudent()和getStudent("axuebin")时都会报错。
let
getStudent()
getStudent("axuebin")
原因:
如果用const来声明对象,则对象中的值可以修改。
const
JavaScript引擎在扫面代码发现声明变量时,遇到var则提升到作用域顶部,遇到let和const则放到TDZ中。当执行了变量声明语句后,TDZ中的变量才能正常访问。
我们经常使用for循环:
for(var i=0;i<10;i++){ console.log(i); //0,1,2,3,4,5,6,7,8,9 } console.log(i) //10
发现了什么?
在for循环执行后,我们仍然可以访问到变量i。
i
So easy ~ 把var换成let就解决了~
for(let i=0;i<10;i++){ console.log(i); //0,1,2,3,4,5,6,7,8,9 } console.log(i) //i is not defined
还记得当初讲闭包时setTimeout循环各一秒输出i的那个例子吗~
曾经熟悉的你 ~
for(var i=0;i<10;i++){ setTimeout(function(){ console.log(i); //10,10,10..... },1000) }
很显然,上面的代码输出了10次的10,setTimeout在执行了循环之后才执行,此时i已经是10了~
setTimeout
之前,我们这样做 ~
for(var i=0;i<10;i++){ setTimeout((function(i){ console.log(i); //0,1,2,3,4,5,6,7,8,9 })(i),1000) }
现在,我们这样做 ~ 来看看把var改成let会怎样~
for(let i=0;i<10;i++){ setTimeout(function(){ console.log(i); //0,1,2,3,4,5,6,7,8,9 },1000) }
nice~
在全局作用域下声明的时
window.
The text was updated successfully, but these errors were encountered:
No branches or pull requests
之前看《深入理解es6》的笔记。。。
var声明及变量提升机制
在ES6之前,在函数作用域中或者全局作用域中通过
var
关键字来声明变量,无论是在代码的哪个位置,这条声明语句都会提到最顶部来执行,这就是变量声明提升。注意:只是声明提升,初始化并没有提升。
看一个例子:
如果按照预想的代码的执行顺序,当
name
有值时才会创建变量age
,可是执行代码发现,即使不传入name
,判断语句外的输出语句并没有报错,而是输出undefined
。这就是变量声明提升。
块级声明
ES6前是没有块级作用域的,比如
{}
外可以访问内部的变量。let声明
和上文一样的代码,只是将
age
的命名关键字从var
改成了let
,在执行getStudent()
和getStudent("axuebin")
时都会报错。原因:
age
变量将立即被销毁name
为空,则永远都不会创建age
变量const声明
如果用
const
来声明对象,则对象中的值可以修改。临时死区(Temporal Dead Zone)
JavaScript引擎在扫面代码发现声明变量时,遇到
var
则提升到作用域顶部,遇到let
和const
则放到TDZ中。当执行了变量声明语句后,TDZ中的变量才能正常访问。循环中的块作用域绑定
我们经常使用for循环:
发现了什么?
在for循环执行后,我们仍然可以访问到变量
i
。So easy ~ 把
var
换成let
就解决了~还记得当初讲闭包时setTimeout循环各一秒输出i的那个例子吗~
曾经熟悉的你 ~
很显然,上面的代码输出了10次的10,
setTimeout
在执行了循环之后才执行,此时i
已经是10了~之前,我们这样做 ~
现在,我们这样做 ~ 来看看把
var
改成let
会怎样~nice~
全局块作用域绑定
在全局作用域下声明的时
var
会覆盖window对象中的属性let
和const
会屏蔽,而不是覆盖,用window.
还能访问到The text was updated successfully, but these errors were encountered: