[关闭]
@TryLoveCatch 2016-11-07T08:09:16.000000Z 字数 1224 阅读 1107

JavaScript核心概念之声明提升(hoisting)

javascript核心概念


前言

  一般来讲,我认为javascript代码在执行时是由上到下一行一行执行的。但实际上这并不完全正确,主要是因为声明提升的存在,包括变量声明和函数声明。

重复声明问题

  1. var a = 1;
  2. var a;
  3. console.log(a);//1
  1. var a = 1;
  2. var a = 2;
  3. console.log(a);//2
  1. function a(){
  2. console.log(1);
  3. }
  4. function a(){
  5. console.log(2);
  6. }
  7. a();//2

  上面三个例子可知,变量的重复声明是无用的,但是赋值操作是成功的,而函数的重复声明会覆盖前面的声明

变量声明提升

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

  按照我原本的想法,第一行应该报错才对啊,但是并没有,这就是变量声明提升,上面的代码,相当于

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

  这样就比较清楚,很好理解为什么是undefined了。为什么会这样子呢?

  javascript在编译阶段,会找到所有的声明,包括变量和函数在内的所有声明都会在任何代码被执行前首先被处理。所以,声明是在编译阶段,而赋值是在执行阶段

  1. var a = 2 ;

  不论这句卸载哪里,都会被分解升两步:

  1. var a;
  2. a = 2;

函数声明提升

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

  和变量声明一样,依然可以顺利执行,这里也是做了提升,所以上面的代码,相当于

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

  函数声明可以提升,但是函数表达式不会提升。

  1. foo();//TypeError: foo is not a function
  2. var foo = function(){
  3. console.log(1);
  4. }

  终于报错了,上面这个代码,相当于:

  1. var foo;
  2. foo();//TypeError: foo is not a function
  3. foo = function(){
  4. console.log(1);
  5. }

优先级

  实现说结论,函数优先。
  上例子

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

  继续改造一下

  1. function foo() {};
  2. var foo;
  3. console.log(typeof foo);//'function'
  4. foo = 1;
  5. console.log(typeof foo);//'number'

第二行,重复声明,被忽略了

结论

  1. 变量声明和函数声明都会提升
  2. javascript编译阶段会找到所有声明,并提升。声明在编译阶段,赋值在执行阶段
  3. 变量重复声明,无效,但赋值操作会成功,而函数重复声明会覆盖
  4. 函数声明优先级高于变量声明
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注