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

 更新时间:2023年08月22日 10:24:15   作者:fishenal  
这篇文章主要介绍了You-Dont-Know-JS作用域学习文档,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

引言

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

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

JS的编译

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

  • 标记+词法分析 Tokenizing/Lexing:: 把程序语言切成一段一段的片段,称之为tokens。比如,程序中的 var a = 2;,会被切成如下tokens:var, a, =, 2, ;。
  • 解析 Parsing: 把token流转换成树,是嵌套元素形式,符合语法结构和规则,这个树被称之为"AST" (Abstract Syntax Tree).
  • var a = 2;的树,开始于顶层节点 VariableDeclaration, 包含子节点 Identifier (值 a), 另外一个子节点 AssignmentExpression 包含另外子节点 NumericLiteral (值 2).
  • 代码生成 Code-Generation: 这个过程是把AST转换成可执行代码, 这部分各程序语言和个平台之间会有极大的不同。 所以,刨除细节,var a = 2;会被转换成机器语言,在内存中创建一个变量 a,而后把值储存其中。

编译器对赋值的操作

当编译器遇到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 作用域的资料请关注脚本之家其它相关文章!

相关文章

  • 微信小程序 location API接口详解及实例代码

    微信小程序 location API接口详解及实例代码

    这篇文章主要介绍了微信小程序 location API接口相关资料,这里详细介绍了location API接口并附简单实例代码,需要的朋友可以参考下
    2016-10-10
  • Dom-api MutationObserver使用方法详解

    Dom-api MutationObserver使用方法详解

    这篇文章主要为大家介绍了Dom-api MutationObserver使用方法详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-11-11
  • JSON Schema概念及使用场景

    JSON Schema概念及使用场景

    这篇文章主要为大家介绍了JSON Schema概念及使用场景示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-07-07
  • JavaScript中使用toLocaleString数字格式化处理详解

    JavaScript中使用toLocaleString数字格式化处理详解

    这篇文章主要为大家介绍了JavaScript中使用toLocaleString数字格式化处理详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-08-08
  • JavaScript内置对象介绍

    JavaScript内置对象介绍

    这篇文章主要介绍了JavaScript内置对象,内置对象就是指 JS 语言自带的一些对象,这些对象供开发者使用,并提供了一些常用的或是最基本而必要的功能,下面我们一起进入文章了解更多详细内容
    2021-12-12
  • 一文详解js基本类型与引用类型的区别

    一文详解js基本类型与引用类型的区别

    这篇文章主要为大家介绍了js基本类型与引用类型的区别详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-06-06
  • JS前端实现fsm有限状态机实例详解

    JS前端实现fsm有限状态机实例详解

    这篇文章主要为大家介绍了JS前端实现fsm有限状态机实例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • 详解HTML5 使用video标签实现选择摄像头功能

    详解HTML5 使用video标签实现选择摄像头功能

    这篇文章主要介绍了详解HTML5 使用video标签实现选择摄像头功能的相关资料,希望通过本文能帮助到大家,实现这样的功能,需要的朋友可以参考下
    2017-10-10
  • JavaScript编程中实现对象封装特性的实例讲解

    JavaScript编程中实现对象封装特性的实例讲解

    JavaScript可以在一定程度上以面向对象方式进行编程,而封装是面向对象中的一个重要特性,本文就来分享阮一峰老师对JavaScript编程中实现对象封装特性的实例讲解
    2016-06-06
  • JS数组方法some、every和find的使用详情

    JS数组方法some、every和find的使用详情

    这篇文章 要给大家介绍的是JS数组方法some、every和find的使用的一些相关资料,感兴趣的小伙伴一起来学习吧
    2021-09-09

最新评论