zoukankan      html  css  js  c++  java
  • You Don't Know JS: Scope & Closures (第2章: Lexical Scope)

    2种主要的models for how scope work.

    最普遍的是Lexical Scope.

    另一种 Dynamic Scope。(在Appendix a中介绍。和Lexical Scope 进行对比)


    Lex-time  

    lexical scope is scope that is defined at lexing time. 

    lexical scope是基于变量和blocks of scope被创建(被你,在write time)。

    不知道这是啥玩意!

    我的理解就是定义作用域的有效范围的时间。

    Look-ups

    Scop look-ups once it finds the first match!

    相同的标志符name可以在不同层的nested scope被定义。这称为shadowing遮挡,内identifier遮挡了外部identifier。

    忽略shadowing,作用域查询总是在最内层作用域开始执行,然后bubble up, 直到找到第一个匹配并停止。

    ⚠️

    全局变量自动成为全局对象的属性(window in browser, etc.), 所以可以不直接的通过它的lexical name来引用一个全局变量,而是非直接的通过全局对象的属性的方式引用:window.a

    因此全局变量即使被遮盖shadowed, 也可以进行存取。

    无论一个函数从哪里引用,如果引用,它的lexical作用域在它声明declared时就定义好了!


    Cheating Lexical

    如何在运行时间,欺骗/修改 Lexical作用域?

    JS有2个机制。但都不被wider社团赞成!被认为是坏的实践!

    看一下这2个机制:

    eval

    动态创建代码,(Ruby内也有eval方法,也是用于动态创建的)

    在开发者定义函数时,Lexical作用域内没有定义的变量/函数.

    通过eval(), 在函数被创建后,在调用这个函数时,创建一个内部变量/函数。

    严格模式下,报错❌ 

    动态创建,极少使用。

     

    with关键字(已经被遗弃,不看了)

    Performance

    不要使用eval() . JS Engine有许多执行优化,在编译阶段。其中一些优化能够静态地分析代码。

    变量和函数声明提前定义好的话,在执行期间,优化就可以花费较少精力来解决identifiers。

     如果使用eval(), 这些优化就没有效果了,甚至不会执行。

    没有优化,代码运行就会变慢!!

    Review

    Lexical Scope意思是scope被定义,由开发阶段决定函数在哪里被声明。

    lexing阶段的编译能够知道:所有的identifiers被定义在哪,和如何被定义的,并因此预言它们(变量/函数)如何在执行阶段被查询。

    eval()造成Lexical Scope被欺骗/修改。导致了负面效果。

    即:Engine不能够预先知道在编译阶段scope如何查询,也就无法优化编译阶段。导致代码运行变慢。

    不要使用!!eval()



  • 相关阅读:
    Seaslog高性能日志系统学习
    同步、异步与阻塞、非阻塞、协程
    SQL常用增删改查语句
    js里的document对象大全(DOM操作)
    php的cURL资源的初步使用
    hive学习笔记(初级)
    使用NSIS制作可执行程序的安装包
    C#设置一个控件可以鼠标拖动
    C#画图超出屏幕的部分无法显示的解决方法
    C#获取当前不同网卡对应的iP
  • 原文地址:https://www.cnblogs.com/chentianwei/p/9737669.html
Copyright © 2011-2022 走看看