- 立即执行函数表达式(IIFE)
var a = 2;
(function foo() {
var a = 3;
console.log(a);//3
})();//IIFE
console.log(a);//2
输出:3 2
foo绑定在函数表达式自身的函数中而不是所在作用域,使值为3的变量a只能在{..}内被访问。 且foo变量名不会污染外部作用域。
var a=2;
(function IIFE(global) {//参数名为global
var a=3;
console.log(a);//3
console.log(global.a);//2
})(window);//将window对象的引用传递进去
console.log(a);//2
输出:3 2 2
立即执行函数表达式的传参版本。
//倒置代码运行顺序
var a=2;
(function iife(def) {
def(window);
})(function def(global) {
var a=3;
console.log(a);//3
console.log(global.a);//2
});
console.log(a);
输出:3 2 2
同上。
- 作用域
try {
undefined();//执行一个非法操作来制造异常
} catch(err) {
console.log(err);//TypeError: undefined is not a function
}
console.log(err);//Uncaught ReferenceError: err is not defined
说明:err仅存在catch分句内部。
var foo=true;
if(foo) {
let bar=foo*2;
var b = foo*3;
console.log(b);
console.log(bar);
}
console.log(b);
console.log(bar);
输出:
3
2
3
Uncaught ReferenceError: bar is not defined
let关键字将变量绑定到所在作用域,所以在全局作用域找不到变量bar。
for(var i=0; i<10; ++i) {
console.log(i);
}
console.log(i);
输出:1 2 3 4 5 6 7 8 9 10
for(let i=0; i<10; ++i) {
console.log(i);
}
console.log(i);
输出:1 2 3 4 5 6 7 8 9 Uncaught ReferenceError: i is not defined
var foo=true;
if(foo) {
var a=2;
const b=3;
console.log(a);
console.log(b);
a=3;
b=4;
}
console.log(a);
console.log(b);
输出:2 3 Uncaught TypeError: Assignment to constant variable.
在为b赋值时直接报错,因为const的值是固定的,试图修改会引起错误。
如果将b=4;
注释掉,则
输出:2 3 3 Uncaught ReferenceError: b is not defined
const与let一样,将变量绑定到所在作用域。
- 作用域提升
总结:变量和函数声明被提升到最上面,函数表达式不会被提升。
a=2;
var a;
console.log(a);
console.log(b);
var b=2;
/*以上代码相当于
var a;
var b;
a=2;
console.log(a);
console.log(b);
b=2;*/
输出:2 undefinedvar a;
定义声明在 编译 阶段进行a=2;
赋值声明在原地等待 执行 阶段
变量a的定义声明var a;
被提升到最上面,即 a=2
之前,所以没有报错undefined.
foo();//1
var foo;
function foo() {
console.log(1);
}
foo=function() {
console.log(2);
}
/*以上代码相当于
function foo() {
console.log(1);
}
foo();
foo=function() {
console.log(2);
}
输出:1
函数foo的声明var foo;
被提升到最上面。
注:函数首先被提升,然后是变量。且,函数声明可覆盖。
代码引用自《你不知道的JavaScript》系列,部分有更改。