你不知道的JavaScript(二)变量提升

xiaoxiao2021-02-28  63

变量提升原理

看下面的简单例子:

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

JavaScript会将上面的声明看成两个声明:var a;和a=2;。第一个定义声明在编译阶段进行,第二个赋值声明会被留在原地等待执行阶段。 第一个代码片段会以如下形式进行处理:

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

这个过程就好像变量声明(函数声明也一样)从他们在代码中出现的位置被“移动”到了最上面,这个过程就叫作提升。

函数优先

函数声明和变量声明都会被提升,但是有一个值得注意的细节:函数首先会被提升,然后才是变量。 考虑下面的代码:

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

结果会输出1,而不是2。这个代码片段会被引擎理解为如下形式:

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

尽管var foo 出现在function foo()的声明之前,但它是重复的声明,因此被忽略,因为函数的声明会被提升到普通变量之前。 虽然重复的var声明会被忽略掉,但是出现在后面的函数声明能够覆盖之前的声明:

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

以上这些内容虽然听起来没有太大用处,但是它说明了在同一个作用域中进行重复定义是非常糟糕的,而且经常会导致各种奇怪的问题。 一个普通快内部的函数声明通常会被提升到所在作用域的顶部,这个过程并不会像下面的代码暗示的那样可以被条件判断所控制:

foo(); var a=true; if(a) { function foo() { console.log('a'); } } else { function foo() { console.log('b') } }

上述代码会被理解为如下形式:

function foo() {console.log('b')}; var a; foo(); a=true; if(a) {} else{}

所以这个行为并不可靠,应该尽可能避免在块内部声明函数。

转载请注明原文地址: https://www.6miu.com/read-77218.html

最新回复(0)