Javascript吊装

Javascript hoisting

我正在学习javascript提升功能,发现以下代码真的很混乱:

var a = 1;
function b() {
    a = 10;
    return;
    function a() {}
}
b();
alert(a);

输出为1。据我所知,由于hoisting,上面的代码相当于

var a;
function b() {      
    function a() {}
    a=10;
    return;
}
a=1;
b();
alert(a);

functionvariable 同名 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() {}
}

与此基本相同,因为 hoisting 将函数推到其作用域的顶部:

function b() {      
    function a() {}
    a = 10;
    return;
}

另外需要注意的是,function a() {}和写var a = function() {}是一样的。所以现在,我们有这样的东西:

function b() {      
    var a = function() {}
    a = 10;
    return;
}

由于在函数 b() 内部声明了一个名为 a 的变量,b() 仅使用和更改 that a 在其本地范围内,因此在函数 b() 之外声明的 a 保持不变。

函数和变量同名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)

函数参数隐含地局部于变量,因此它们自动 "shadow" 共享相同名称的全局变量。

如果我们省略function a() {},那么全局a的值将从函数b内部赋值()

var a = 1;
function b() {
  a = 10; 
}
b();
console.log(a); // 10

函数b()[=中使用函数a(){} 29=] 与我们声明 var a=10; 的效果相同 这会将 a 的范围限制在 函数 b() 内,并且不会超出其范围。

var a = 1;
function b() {
  var a = 10; 
}
b();
console.log(a); // 1

这是一篇关于提升的易读文章: https://medium.com/@bouguerra_70679/hoisting-464979b60282

What happens when a function and a variable has the same name a?

在 JavaScript 中,functions 是第一个 class 对象,因为它们可以像任何其他对象一样拥有属性和方法。

(区别于其他对象的地方在于可以调用函数)

换句话说,函数被定义为函数类型的变量,可以传递给其他函数,存储在数组中等

所以当一个函数和一个变量同名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