标签:size com 函数表达式 closure width 一个 value block ccf
变量附加到哪个层次的scope,由它们在哪里和如何声明(let, var)来决定。
Function scope/Block scope都有相同的法则:任何变量在一个scope内声明,则这个变量附加到这个作用域上。
但有一个细节问题:当声明declarations出现在一个作用域中的不同的位置的时候,scope附加如何与declarations协作?
temptation: a strong desire to have or do sth even thought you know you should not(邪念,诱惑人的事物)
当程序执行时,JS 代码被一行行,从上到下的顺序被解译。但有例外:
a = 2; var a; console.log( a ); 输出2
可是:
console.log( a ); var a = 2;
//输出undefined
怎么回事? 一个先有鸡还是先有蛋的问题。 the declaration是蛋, assignment是鸡。
Engine实际是先编译JS code,在interprtes it之前。
编译器先声明变量,然后Engine在Scope中查询这个变量,如果发现就分配它。
所以思考事情的最好的方式是:
所有的声明declarations,包括变量和函数,被首先处理processed。在你的代码被执行executed前。
var a = 2; 其实是2个statements: var a;和a = 2;
var a 是声明,在编译阶段被处理;
a = 2是assignment, 会留在执行阶段execution phase处理。
所以,前2个例子就可以理解了:
//第一个例子: var a; a = 2; console.log(a); // 2 //第二个例子: var a; console.log(a); //undefined a = 2;
结论:先有蛋(declarations),后有?? assignment.
foo(); // not ReferenceError, but TypeError!
var foo = function bar() {
// ...
};
Uncaught TypeError: foo is not a function
解释:
var foo被提升hoisting,但它没有value。
使用foo(),就是认为foo的值是函数,用()执行函数。
typeof foo //undefined
所有,提示?,foo不是一个函数,不能使用()!
(表达式和声明的区分见第三章,Function as Scope)
另一个例子:
foo(); // TypeError ,foo is not a function
bar(); // ReferenceError, (bar是函数,但是)bar is not defined
var foo = function bar() {
// ...
};
等同于:
var foo;
foo(); // TypeError
bar(); // ReferenceError
foo = function() {
var bar = ...self...
// 证明作为表达式,bar 只在内部{ .. }被使用
}
foo(); // 3
function foo() { //hoisting ,第一行
console.log( 1 );
}
var foo = function() { //多重var声明,被忽略,不会hoisting。
console.log( 2 ); //这里重写了foo函数。
};
function foo() { //hoisting,第二行
console.log( 3 );
}
foo() //输出2
ES7最新版:块内函数声明, 要小心使用!foo没有hoisting到全局作用域!!
var a = 2;其实是2部分,var a 是在编译阶段处理, =2在执行阶段处理
所有声明都首先被处理!在它们执行前!
分配, 甚至分配一个函数表达式,都不会被hoisted!
小心duplicate declarations。尤其是混合了正常的var声明和函数声明,要避免这种使用!
写代码先写声明,是好的习惯!!
You Don't Know JS: Scope & Closures (第4章: Hoisting)
标签:size com 函数表达式 closure width 一个 value block ccf
原文地址:https://www.cnblogs.com/chentianwei/p/9739698.html