在牛客网刷JS题目时,遇到JS的hoisting这个知识点,不懂,于是去百度。我认为其中有位博主写的蛮好的,于是转载一篇文章。地址:http://www.cnblogs.com/fcaa/p/5948438.html
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------分割线
从网上看到这么一段代码:
var c = 2;
function c(){
c = 22;
console.log("c="+c);
}
c();//会报错,变量提升机制导致的(c is not a function)
问运行结果是什么,然后不假思索的就以为是22,因为c=22这行看起来就是对外面的全局变量c重新定义了
但是实际上不是的,这句话不会执行到c()的时候会报错(number is not a function),有点蒙蔽,这是怎么了,查了好久,才知道js有个提升机制,变量和函数(函数声明的方式有提升机制,函数表达式没有这个机制)都有提升机制,而且函数提升机制的优先级高于变量的,这也就是说当函数名和变量名相同的时候,拿上面这个例子来说,c被提升到代码最前端,并且被赋值为一个函数,然后才会 被赋值为2,上面的代码等效于下面这个:
var c = function c(){
c = 22;
console.log("c="+c);
};
c = 2;
c();
执行的时候,c先被赋值为一个函数,然后紧接着又被赋值为数字2,这样在这句赋值语句下面执行c()的时候,c就不是函数了,而是数字,如果在c = 2;这句话的上面执行c()的话,就没有问题了,结果是c = 22;
再来看另一个问题,函数声明和函数表达式有什么不同,就是下面这两种情况:
d();//1
function d(){//方式1
alert("1");
}
d();//undefined is not a function
var d = function(){//方式2
alert("1");
};
这两种声明函数方式不同之一在于:
方式1可以在d声明之前使用d()来调用函数,方式2却不可以
这个也是可以用变量提升机制来解释的,方式1的写法和下面这个等价:
var d = function d(){
alert("1");
};
d();
所以执行没有问题,但是第二种写法的函数就没有变量提升机制,好像也可以用这个方式来解释,第二种写法等价于下面这样:
var d;
d();
d = function(){
alert("1")
};
这样的话,执行d()的时候,d还没有被定义为函数,只是被声明了,所以会执行报错。(这样应该可以解释的通,不对的地方,请务必让我知道)
来看个复杂点的例子:
var a = 1;
function b() { //变量提升机制:如这个例子所示,执行b()时
console.log(a); // function a(){}
a = 10; //这可不是对外面的全局变量a定义哦
console.log(a); //10(局部变量)
var a = 11;
console.log(a); //11(局部变量)
return;
function a(){
alert("abc");
}
}
b();
console.log(a); //1(全局变量)
上面的例子等价于下面这样:
var b = function b(){
var a = function a(){
alert("abc");
}
console.log(a);
a = 10;
console.log(a);
a = 11;
console.log(a);
return;
}
var a;
a = 1;
b();
console.log(a);