JavaScript声明提升
2018-03-03 23:09
169 查看
声明提升就好像把声明(变量声明和函数声明)从它们所在代码中出现的位置移到了最上面。直觉上我们会以为JavaScript代码是由上到下一行一行执行的,但实际上这并不完全正确,还要考虑声明提升的存在。
1. 考虑下面关于变量声明提升的代码:
按照由上到下一行一行执行的思路:var a 声明在 a = 2 之后,所以a被重新赋值了,最后会输出undefined?
按照由上到下一行一行执行的思路:变量a在使用前没有先声明,所以会抛出ReferenceError异常?
代码执行一下的话,我们会发现答案是2 和 undefined,所以上面的思路是行不通的。正确的思路是:包括变量和函数在内的所有声明都会在任何代码被执行前首先被处理,就好像变量和函数声明会从它们所在代码中出现的位置被“移动”到了最上面,这个过程也就是提升。
我们习惯把var a = 2; 看做一个声明,而实际上JavaScript引擎并不这么认为。它将 var a 和 a = 2 当做两个单独的声明, 第一个是编译阶段的任务,而第二个则是执行阶段的任务。只有声明本身会被提升,而赋值或其他运行逻辑会留在原地。
按照声明提升的思路(相当于把所有声明提升的部分移到代码的最上面然后在一行一行顺序执行),上面的两段代码相当于:
这样的话,再按照由上到下一行一行执行的思路,答案很明显就是2 和 undefined了。
2. 考虑下面关于函数声明提升的代码:
按照声明提升的思路(相当于把所有声明提升的部分移到代码的最上面然后在一行一行顺序执行),上面的两段代码相当于:
这样的话,再按照由上到下一行一行执行的思路,答案就是undefined了。
注:函数声明会被提升,但是函数表达式却不会被提升。
函数声明和变量声明都会被提升,但是函数会首先提升,然后才是变量。即函数声明的优先级要大于变量声明。
3. 考虑下面关于声明提升优先级的代码:
按照声明提升的思路(相当于把所有声明提升的部分移到代码的最上面然后在一行一行顺序执行),上面的两段代码相当于:
尽管var foo出现在function foo之前,但是函数提升的优先级要大于变量提升,所以 function foo(){} 会在var foo之前;但是var foo是重复声明所以被忽略了,所以最终输出1。
注: 尽管重复的var声明会被忽略掉,但出现在后面的函数声明还是可以覆盖前面的。
4. 考察声明提升的例子
答案:
JavaScript系列文章:变量提升和函数提升
1. 考虑下面关于变量声明提升的代码:
a = 2; var a; console.log(a); // ??
按照由上到下一行一行执行的思路:var a 声明在 a = 2 之后,所以a被重新赋值了,最后会输出undefined?
console.log(a); var a = 2; // ??
按照由上到下一行一行执行的思路:变量a在使用前没有先声明,所以会抛出ReferenceError异常?
代码执行一下的话,我们会发现答案是2 和 undefined,所以上面的思路是行不通的。正确的思路是:包括变量和函数在内的所有声明都会在任何代码被执行前首先被处理,就好像变量和函数声明会从它们所在代码中出现的位置被“移动”到了最上面,这个过程也就是提升。
我们习惯把var a = 2; 看做一个声明,而实际上JavaScript引擎并不这么认为。它将 var a 和 a = 2 当做两个单独的声明, 第一个是编译阶段的任务,而第二个则是执行阶段的任务。只有声明本身会被提升,而赋值或其他运行逻辑会留在原地。
按照声明提升的思路(相当于把所有声明提升的部分移到代码的最上面然后在一行一行顺序执行),上面的两段代码相当于:
var a; a = 2; console.log(a); // 2
var a; console.log(a); // undefined a = 2;
这样的话,再按照由上到下一行一行执行的思路,答案很明显就是2 和 undefined了。
2. 考虑下面关于函数声明提升的代码:
fn(); function fn(){ console.log(a); // ?? var a = 2; }
按照声明提升的思路(相当于把所有声明提升的部分移到代码的最上面然后在一行一行顺序执行),上面的两段代码相当于:
function fn(){ var a; console.log(a); // undefined a = 2; } fn();
这样的话,再按照由上到下一行一行执行的思路,答案就是undefined了。
注:函数声明会被提升,但是函数表达式却不会被提升。
fn(); var fn = function (){ console.log(a); var a = 2; } // Uncaught TypeError: fn is not a function
函数声明和变量声明都会被提升,但是函数会首先提升,然后才是变量。即函数声明的优先级要大于变量声明。
3. 考虑下面关于声明提升优先级的代码:
var foo; foo(); // ?? function foo(){ console.log(1); }
按照声明提升的思路(相当于把所有声明提升的部分移到代码的最上面然后在一行一行顺序执行),上面的两段代码相当于:
function foo(){ console.log(1); } var foo; // 重复声明,被忽略 foo(); // 1
尽管var foo出现在function foo之前,但是函数提升的优先级要大于变量提升,所以 function foo(){} 会在var foo之前;但是var foo是重复声明所以被忽略了,所以最终输出1。
注: 尽管重复的var声明会被忽略掉,但出现在后面的函数声明还是可以覆盖前面的。
var foo; foo(); // 3 function foo(){ console.log(1); } function foo(){ console.log(3); } foo = function(){ console.log(2); }
4. 考察声明提升的例子
alert(a); // ?? a(); // ?? var a = 3; function a(){ alert(10) } alert(a) // ?? a = 6; a(); // ??
答案:
alert(a); // function a(){ alert(10) } a(); // 10 var a = 3; function a(){ alert(10) } alert(a) // 3 a = 6 4000 ; a(); // Uncaught TypeError: a is not a function
参考阅读
你不知道的JavaScript上卷>第4章提升JavaScript系列文章:变量提升和函数提升
相关文章推荐
- 你不知道的JavaScript--Item6 var预解析与函数声明提升(hoist )
- javascript的变量声明和函数声明提升
- javascript中的函数声明提升
- [Effective JavaScript 笔记] 第12条:理解变量声明提升
- JavaScript中变量和函数声明的提升
- 你不知道的JavaScript--Item6 var预解析与函数声明提升(hoist )
- javascript的变量声明和函数声明提升
- JavaScript中函数声明,函数提升,对象属性和原型属性等问题
- JavaScript学习--Item6 var预解析与函数声明提升(hoist )
- JavaScript 函数总体概述(函数声明/参数传递/返回值/加载/变量和作用域/变量声明提升/匿名函数/回调函数)
- javascript的变量声明和函数声明提升
- javascript中的变量声明提升和函数声明提升
- [JavaScript,ES6]函数声明提升和预解析的总结和试验
- javascript的变量声明和函数声明提升
- javascript声明提升现象及严格模式
- javaScript中的函数声明提升---函数声明与函数表达式
- 浅谈JavaScript--声明提升
- javascript的变量声明和函数声明提升
- JavaScript机制:变量&函数声明提升的那些事
- javascript的变量声明提升