浅谈JavaScript--声明提升,JavaScript常见错误

JavaScript是一种动态语言,不同于CJava等静态语言先编译后执行,

所以代码中的执行顺序并不像你看到的那样执行,有个词你需要知道声明提升

下面我们就来聊聊声明提升。

抛砖

 

1

2

3

 

a = 1;

var a;

console.log(a); // 1

结果是1,不是undefined。虽然在var a;a = 1;后面,但是存在声明提升,等价于:

 

1

2

3

 

var a;

a = 1;

console.log(a);

 

再抛一块

 

1

2

 

console.log(a); // undefined

var a = 1;

为什么这次结果就是undefined了,声明同样提升了,但是。。。等下再告诉你,上面的代码等价于:

 

1

2

3

 

var a;

console.log(a); // undefined

a = 2;

 

也就是说声明虽然提升了,但是赋值操作(执行)被留在了本身的位置。

原理

引擎在对解释js的代码的时候,首先进行的是编译。
找到所有的声明,并用合适的作用域把它们关联起来。

so,var a = 2,js会将其看成两个声明var a; a = 2;

第三块砖

 

1

2

3

4

5

6

 

foo();

function foo() {

console.log(a); // undefined

var a = 2;

}

这个就很好理解了吧,那么你回答下一个

 

1

2

3

4

5

6

 

foo();

var foo = function bar() {

console.log(a);

var a = 2;

}

 

先别说你的答案,估计你也猜错了,不是undefined也不是2

因为还没执行到bar()foo()就已经报错了TypeError,函数声明可以提升,但是函数表达式的声明不能提升。

即使是具名函数表达式,在名称标识符在赋值之前也无法在作用域中使用:

 

1

2

3

4

5

6

7

 

foo(); // TypeError;

bar(); // ReferenceError;

var foo = function bar() {

console.log(a);

var a = 2;

}

 

其实经过提升之后,代码变成了:

 

1

2

3

4

5

6

7

8

9

10

11

 

var foo;

foo(); // TypeError;

bar(); // ReferenceError;

foo = function () {

var bar = function () {

console.log(a);

var a = 2;

}

}

 

优先原则

 

1

2

3

4

5

6

7

8

9

10

11

 

foo(); // 1

var foo;

function foo () {

console.log(1);

}

foo = function () {

console.log(2);

}

输出的是1,而不是2。

 

1

2

 

var foo;

function foo () {...}

 

这两个都是声明,但是在声明中函数会首先被提升(var foo同时被忽略了)。也就变成了:

 

1

2

3

4

5

6

7

8

 

function foo() {

console.log(1);

}

foo(); // 1

foo = function () {

console.log(2);

}

 

: 重复声明,后面函数声明会覆盖前面的。

 

1

2

3

4

5

6

7

8

9

10

11

12

13

 

foo(); // 3

function foo() {

console.log(1);

}

foo = function () {

console.log(2);

}

function foo() {

console.log(3);

}

大爷,请赏我点铜板买喵粮自己吃,您的支持将鼓励我继续创作!(支付宝)

总结

为了避免踩坑,我们要做到先声明,避免重复声明

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值