JavaScript

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > JS 作用域

You-Dont-Know-JS作用域学习文档

作者:fishenal

这篇文章主要介绍了You-Dont-Know-JS作用域学习文档,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

引言

You-Dont-Know-JS是github上一个拥有9000多枚星星的JS教学文档,评价很高,为了避免和其他翻译文一样,容易陷入不宜读的混乱,也试图避免原文中过多数的术语导致我露怯,我只提取提取我理解的一些点,通俗的讲出来。今天先从第一章作用域开始吧:

原文我的翻译folk,希望有识之士能跟我共同完成

JS的编译

js和传统语言一样,也需要编译执行,编译的过程通常分三步:

编译器对赋值的操作

当编译器遇到var a,它会询问域是否存在变量a,如果存在编译器忽略这个声明,如果不存在编译器要求域声明一个新变量a给自己。

编译器而后为引擎产生可执行代码,处理a = 2, 引擎首先询问域是否有这个变量,如果没有执行其他操作。

两种引用

LHS(Left-hand Side)引用和 RHS(Right-hand Side)引用,对于编译器来说,LHS指变量用于赋值,RHS是指变量用于取值。

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

foo( 2 );

这里,foo(), 引用(变量)foo是RHS引用,因为它是用于取值的操作(将函数foo的值取出来),参数a被隐含赋值2,a = 2这里的引用a是LHS引用,因为它用于赋值。console.log(a)里面的a也是LHS引用,因为它用于获取a的值。

这里说明的是, 代码里的变量, 对于编译器来说有两种类型,用于获取它值的是一种,本身是用于被赋值的是另外一种。

嵌套域 (Nested Scope)

嵌套域很好理解,如下代码

function foo(a) {
    console.log( a + b );
}

var b = 2;

foo( 2 ); // 4

foo函数域中没有变量b,当引用b被调用的时候,程序会逐级往上查找,直到找到变量b,最顶层为全局变量 (global scope),如下图所示:

错误

但是各位有没有想过一个问题,被赋值的引用(LHS)如果本域内不存在会产生什么情况?当然,大多数人都经历过ReferenceError,引用错误。

当LHS引用(赋值引用)在域中找不到的时候,js引擎会直接抛出错误,而RHS引用(调用引用)如果在域中找不到的时候,js引擎会向上一级域中查找,如果依然没有,会直接在全局域中为你自动创建一个(非严格模式下, 严格模式下也会报ReferenceError错误)。

考虑从如下代码:

function foo(a) {
    console.log( a + b );
}

foo( 2 );

这里的变量b因为在函数域中未定义,所以会报错

function foo(a) {
    b = a;
}

foo( 2 );

这里的变量b也未定义,但是由于是复制操作,系统会为你在外层全局域里自动创建一个。

以上就是You-Dont-Know-JS作用域学习文档的详细内容,更多关于JS 作用域的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文