Javascript吊装
我正在学习Javascript吊装,javascript,hoisting,Javascript,Hoisting,我正在学习javascript提升功能,发现下面的代码非常混乱: var a = 1; function b() { a = 10; return; function a() {} } b(); alert(a); 输出为1。据我所知,由于吊装,上述代码相当于 var a; function b() { function a() {} a=10; return; } a=1; b(); alert(a); 当函数和变量具有相同的名称
javascript
提升功能,发现下面的代码非常混乱:
var a = 1;
function b() {
a = 10;
return;
function a() {}
}
b();
alert(a);
输出为1
。据我所知,由于吊装,上述代码相当于
var a;
function b() {
function a() {}
a=10;
return;
}
a=1;
b();
alert(a);
当
函数
和变量
具有相同的名称a
时会发生什么情况?在b
中,首先将局部变量a
设置为函数,然后将值10
。外部变量a
不受影响,因为它被b
中的局部变量a
遮挡。也许这段大致相当的代码将有助于说明:
var a = 1;
function b() {
var a;
a = function a() { };
a = 10;
return;
}
b(); // Basically a no-op
alert(a);
职能:
function b() {
a = 10;
return;
function a() {}
}
与此基本相同,因为提升
将功能推到其范围的顶部:
function b() {
function a() {}
a = 10;
return;
}
还需要注意的是,function a(){}
与编写var a=function(){}
相同。现在,我们有了这样的东西:
function b() {
var a = function() {}
a = 10;
return;
}
由于在函数b()
内部声明了名为a
的变量,b()
仅在其局部范围内处理和更改该a
,因此在函数b()外部声明的a
)
保持不变。当函数和变量的名称相同时会发生什么
没什么特别的。对a
的一个赋值会覆盖另一个赋值,因为它们都是值
console.log(a) // a points to a function here
var a = 4
console.log(a) // a points to 4 here
function a() {}
console.log(a) // a also points to 4 here!
顺便说一下,如果变量不是函数的局部变量,则函数外部作用域中的变量只能由该函数修改
var a = 4
;(function() {
a = 5
})() // <-- Immediately calling the function here
console.log(a) // a is now 5
;(function() {
a = 6
var a
})()
// a is still 5 because in the previous function,
// a was local to the function's scope
console.log(a)
var a=4
;(功能(){
a=5
})()//如果省略函数a(){},则全局a的值将从函数b()内部赋值
在函数b()中使用函数a(){}将产生与声明var a=10相同的效果强>
这会将a的范围限制在函数b()的内部,并且不会溢出其范围之外
var a = 1;
function b() {
var a = 10;
}
b();
console.log(a); // 1
以下是一篇关于吊装的易读文章:
当函数和变量的名称相同时会发生什么
在JavaScript中,是第一类对象,因为它们可以像任何其他对象一样具有属性和方法
(它们与其他对象的区别在于可以调用函数。)
换句话说,函数被定义为function类型的变量,可以传递给其他函数,存储在数组中,等等
因此,当函数和变量的名称相同时,可能会出现一些冲突,如您的示例所示:
var a;
function b() {
function a() {} // variable a of type function shadows variable a in the outer scope
a=10; // variable a defined in the inner scope is now of number, instead of function any more
return;
}
a=1;
b();
alert(a); // 1
为什么第一个console.log(a)
等于5的原因可能重复?在js
中,一个函数创建了一个新的scrope,那么a=5
的定义不应该在函数
scrope之外生效,因此我认为输出仍然应该是4
@byteBiter所有函数都有自己的局部范围。:)但对于不在局部范围内的所有变量(即不在var
s或参数或函数声明中的变量),函数在其父范围内(即创建函数的范围)查找a
,如果不在该范围内,则转到父范围的父范围,依此类推。这个概念被称为词法范围,它是一个强大的语言特性,使闭包隐式且易于使用。
var a;
function b() {
function a() {} // variable a of type function shadows variable a in the outer scope
a=10; // variable a defined in the inner scope is now of number, instead of function any more
return;
}
a=1;
b();
alert(a); // 1