视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
JavaScript中标识符提升问题_javascript技巧
2020-11-27 21:39:10 责编:小采
文档
 JS 存在变量提升,这个的设计其实是低劣的,或者是语言实现时的一个副作用。它允许变量不声明就可以访问,或声明在后使用在前。新手对于此则很迷惑,甚至许多使用JS多年老手也比较迷惑。但在 ES6 加入 let/const 后,变量Hoisting 就不存在了。

一、 变量未声明,直接使用



报错是自然的

二. 变量声明在末尾



输出 undefined, 结果比上例有所改善,没有报错,代码可以运行,但变量值可能不是程序员所期望的。

三、 变量声明在末尾,同时给变量赋值



结果和 二 相同, 很明显,并不会因为赋值了就输出 1。

二、三 都发生了变量提升(Hoisting),简单定义

变量提升: 在指定作用域里,从代码顺序上看是变量先使用后声明,但运行时变量的 “可访问性” 提升到当前作用域的顶部,其值为 undefined ,没有 “可用性”。

这里强调 “代码顺序” 和 “运行顺序”,是因为多数时候我们写的代码都是顺序执行的,即 “代码顺序” 和 “运行顺序” 是一致的。这也符合人的大脑的思维过程。比如有过 C语言 经验的程序员

#include 
int main() {
 int x = 1;
 printf("%d, ", x); // 1
}

两句代码,先声明整数型 x, 再输出。代码顺序和运行顺序是一致的,即正常运行。

如果顺序反过来

#include 
int main() {
 printf("%d, ", x); // error
 int x = 1;
}

此时,编译都不能通过了。但JS里可以反过来写,见二、三。

因此,有类 C语言 经验的程序员,都很清楚变量需要 先声明后使用,不然会报错。而到了JS里,有 变量提升 现象,可以 先使用后声明,C 的经验用到 JS 里迷惑便出现了。

四、 函数表达式也存在变量提升



但如果想使用这个 func,则无可能



结果func 是 undefined,调用 func 则会报异常。 在上面的定义中提到了 可访问性 和 可用性 对应如下语句。

可访问性:alert(func),输出 undefined,可以运行,可以访问 func。

可用性: func(), 报异常,不能正常调用 func,表示无可用性。

二、三、四 都是使用 var 声明的变量,JS 里函数声明也会存在提升,只是这个 “变量” 比较特殊,它是一个 function 类型(可以作为函数、方法或构造器)。它的名字(标识符)也会提升到当前作用域的顶部。

五、函数声明的名也会提升到当前作用域顶部



我们看到,声明 f1 在代码最末,f1 使用在前,alert(f1) 和 f1() 都正常执行,表示 可访问性 和 可用性 都有了。

前面说了,变量提升(Hoisting)没什么用,属于语言的低劣设计,好的习惯还是 “先声明后使用”。这个特性也会出现在不少大公司面试题里

题1:



题2:



但这一切随着 ES6 的 let/const 到来结束了,ES里除全局变量外,其它都使用 let/const,var 替换成 let 后变量提升就不复存在了。



这强制程序员养成好的习惯,变量需要“先声明再使用”,否则报错。

以下摘自MDN的关于let不在发生变量提升的描述

代码如下:
In ECMAScript 6, let does not hoist the variable to the top of the block. If you reference a variable in a block before the let declaration for that variable is encountered, this results in a ReferenceError, because the variable is in a "temporal dead zone" from the start of the block until the declaration is processed.

用 let 声明变量后,typeof 也不再安全



以前可以用 typeof == 'undefined',来判断是否引入了某lib,比如jQuery



jQuery没有引入,$ 没有声明,这句也不会报错而影响到下面的代码执行,但如果是 let 声明的就会报错了。

以上所述就是本文的全部内容了,希望大家能够喜欢。

下载本文
显示全文
专题