javascript 中的变量提升

JavaScript变量提升及其影响

在JavaScript中,变量提升是一种特性,它会将变量和函数声明提升到作用域顶部,以便在代码执行之前进行解析。这篇文章将详细讨论变量提升的行为以及它对代码执行顺序的影响。

什么是变量提升

变量提升是JavaScript引擎在解析代码时将变量和函数声明提升到作用域顶部的过程。它意味着可以在声明之前使用变量或调用函数,而不会导致错误。

例如:

a = 1;
var a;
console.log(a); // 1
a = 1;
var a;
console.log(a); // 1

实际上,上述代码在编译后的顺序是:

var a;
a = 1;
console.log(a); // 1
var a;
a = 1;
console.log(a); // 1

另外一个例子:

console.log(a); // undefined
var a = 2;
console.log(a); // undefined
var a = 2;

函数优先

函数声明和变量声明都会被提升,但是函数会被首先提升,然后才是变量。

例如:

foo(); // 1
var foo;
function foo() {
    console.log(1);
}
foo = function (){
    console.log(2);
}
foo(); // 1
var foo;
function foo() {
    console.log(1);
}
foo = function (){
    console.log(2);
}

上述代码会输出1。因为JavaScript引擎会将函数声明提升到作用域顶部,相当于以下代码:

function foo(){
    console.log(1);
}
foo();
foo = function(){
    console.log(2);
}
function foo(){
    console.log(1);
}
foo();
foo = function(){
    console.log(2);
}

需要注意的是,重复声明会被忽略,而且只有声明本身会被提升,赋值语句不会被提升。

经典面试题

下面是一个经典的面试题,通过解答这个题目可以理解变量提升、this指针指向、运算符优先级、原型、继承、全局变量污染、对象属性及原型属性优先级等知识。

function Foo() {
    getName = function () { 
        alert (1); 
    };
    return this;
}
Foo.getName = function () { 
    alert (2);
};
Foo.prototype.getName = function () { 
    alert (3);
};
var getName = function () { 
    alert (4);
};
function getName() { 
    alert (5);
}

Foo.getName(); // 2
getName(); // 4
Foo().getName(); // 1
getName(); // 1
new Foo.getName(); // 2
new Foo().getName(); // 3
new new Foo().getName(); // 3
function Foo() {
    getName = function () { 
        alert (1); 
    };
    return this;
}
Foo.getName = function () { 
    alert (2);
};
Foo.prototype.getName = function () { 
    alert (3);
};
var getName = function () { 
    alert (4);
};
function getName() { 
    alert (5);
}

Foo.getName(); // 2
getName(); // 4
Foo().getName(); // 1
getName(); // 1
new Foo.getName(); // 2
new Foo().getName(); // 3
new new Foo().getName(); // 3

希望通过解答上述问题可以深入理解变量定义提升、this指针指向、运算符优先级、原型、继承、全局变量污染、对象属性及原型属性优先级等知识点。

答案如下:

Foo.getName(); // 2
getName(); // 4
Foo().getName(); // 1
getName(); //

 1
new Foo.getName(); // 2
new Foo().getName(); // 3
new new Foo().getName(); // 3
Foo.getName(); // 2
getName(); // 4
Foo().getName(); // 1
getName(); //

 1
new Foo.getName(); // 2
new Foo().getName(); // 3
new new Foo().getName(); // 3

这个面试题涉及了多个概念和知识点,包括函数声明和变量声明的提升、函数和对象的属性访问、this指针的指向等。理解这些概念对于正确解答面试题和编写可靠的JavaScript代码至关重要。

总结起来,理解JavaScript中的变量提升对于编写高效、可读性高的代码是非常重要的。通过掌握变量提升的行为,可以更好地理解代码的执行顺序和结果,避免潜在的错误和不确定性。