javascript复习:变量提升

什么是变量提升,为什么会发生变量提升?
这个问题还是挺经典的,让我们深度的研究一下。

什么情况下发生?

1
2
3
var str = 'hello world';
console.log(str);
// 输出:

以上代码输出 “hello world”,和预期的一样。

实例 2:

1
2
3
console.log(str2);
var str2 = 'hello world';
// 输出: undefined

代码没报错,输出了 “undefined”,按照正常的代码执行操作,不应该是没有定义 “str2”,会报错的么。问题是出在“var str2 = ‘hello world’;”。这就是javascript的变量提升。

深入了解一下

“变量提升”意味着变量和函数的声明会在物理层面移动到代码的最前面,但这么说并不准确。实际上变量和函数声明在代码里的位置是不会动的,而是在编译阶段被放入内存中。

”在编译阶段被放入内存“,这句话道出了变量提升的发生原因。实例 2 在打印 ”str2“的时候内存中已经有”str2“,只是只提升了声明,赋值并没有被提前。就像如下例子:

1
2
3
console.log(num); // Returns undefined
var num;
num = 6;

表达式与函数声明提升时的差异

1. 函数声明提升时,函数本身也会提升到当前作用域的最前面

1
2
3
4
foo()  // 1
function foo() {
console.log('1')
}

2. 函数表达式执行时,只会将变量提升

函数表达式执行时则不然,只会将变量提升,暂赋值undefined,赋值或其他逻辑运行会留在原地

1
2
3
4
foo() // Uncaught TypeError: foo is not a function, 此时的foo为undefined
var foo = function() {
console.log('1')
}

javascript 语法为何如此松散凌乱?怎么解决这样的变量提升导致的莫名报错?

变量提升这个概念只有 js 里才有,可能是语言设计的导致。es6之后,有了新的变量声明关键词”let,const“;

1
2
3
console.log(num); // Uncaught ReferenceError: num is not defined
let num;
num = 6;

变量提升”消失“了,”let“ 关键词发挥了作用

附上一份面试题及答案

选自 https://zhuanlan.zhihu.com/p/139644982

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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 => Foo的静态属性getName
getName(); // 4 => 执行全局环境下的getName
Foo().getName(); // 1 <=>window.getName()
getName(); // 1 => 执行全局环境下的getName
new Foo.getName(); // 2 => 执行Foo的静态属性getName的构造函数
new Foo().getName(); // 3 相当于Foo实例原型上的getName
new new Foo().getName(); // 3 相当于Foo实例原型上的getName的构造函数