作者eight0 (人类)
看板Ajax
标题Re: [问题] Hoisting 问题
时间Sun Feb 19 23:24:23 2017
我觉得原 PO 的问题可能不是 hoisting,而是不知道 test = ... 会把 function test
覆盖掉。不过这篇还是讲 hoisting。
Hoisting 这个「行为」是被人「观察」出来的。以 C 为例子︰
#include <stdio.h>
int a = 1;
int main() {
printf("%d\n", a);
int a = 2;
printf("%d\n", a);
}
得到的结果会是
1
2
但在 JavaScript 中
var a = 1;
function main() {
console.log(a);
var a = 2;
console.log(a);
}
main();
得到的结果是
undefined
2
人们就给出一套解释︰「以 var 定义的变数,会被提到 function scope[1] 的最上面,
而且初始值是 undefined。并且会等到原本的位置(a = 2)才会赋值」,称为
「Hoisting」。(其实这个说法是错的,在定义 var 时并所谓的「初始值」并不一定是
undefined,可能该变数本来就在 scope 内,或是被 function arguments 赋值)
[1]: 关於 scope:
https://is.gd/tcHqDy
事实上 JS 做的事情是︰在进入一个新的 scope 的时候,会把 var, function,
const, let 的变数收集起来,并且把变数名称注册到目前的 scope 中,接着才开始执行
接下来的程式码。
它们之前的差别︰
var 是丢到 function scope,并且可以重覆定义,在未赋值前存取会得到 undefined。
function 也是丢到 function scope,可以重覆定义。若定义是放在 scope 的最外层
(定义位於 function scope 底下,而且不在任何 block scope 内),则会提前赋值,
所以你可以在 function 定义前就使用这个变数。否则就和 var 相同,在未赋值前存
取会得到 undefined。
const 和 let 是丢到 block scope,不能重覆定义,在还未赋值前存取会
ReferenceError。
const 还有一个限制是不能重覆赋值。
至於 const, let 也有 hoisting 现象,解释为「将定义提升到 block scope 的最上
方,但若提前存取会丢出 ReferenceError」,并使用 temporal dead zone 的概念。
要解释这个的话又和 function 的 default parameter 或 for, while 有关……
这里解释得满清楚的︰
http://exploringjs.com/es6/ch_variables.html
如果看了这一堆还很有兴趣的话,可以玩这个︰
http://perfectionkills.com/javascript-quiz-es6/
--
▉▏
▉▏
◢ ▊▎ ◣
◤ ▄▆▄ ◥
◥ ◥ ◤ ◤
▄ ▄
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 111.250.156.252
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/Ajax/M.1487517868.A.B84.html
1F:推 violet90079: 感谢指点~~JavaScript真的好深奥啊Orz 02/19 23:58
2F:推 MangoTW: 推精辟解析 02/20 00:25
3F:推 broo: 多谢解说!有了解一些了! 02/20 23:48
4F:推 kaidouya: 推 04/02 12:12
5F:→ eight0: 这篇文章也很清楚,虽然没有提到 function/for params 05/31 12:19