20200215

@czhang
  • date: 20200215
  • author: czhang

Plan

你不知道的 JavaScript 第一部分 第二第三章

Notes

1. 欺骗词法

1. eval()
    eval 的参数 是以代码形式动态插进来的,对当前词法作用域环境进行修改。

2. with()
    会根据传入的对象,创建一个新的词法作用域,如果该对象没有该属性,会自动创建一个全局变量(非严格模式下)

3. 重点:
    JS引擎在编译阶段会依赖词法分析根据代码的词法静态分析,预先确定所有变量和函数定义的位置,在执行过程中快速的找到标识符。如果使用了 eval 和 with , 引擎无法在编译的时候对作用域在做查找优化 ===> 不要使用 eval() with()

2. 函数作用域

1. 定义: 属于函数的全部变量都可以在整个函数的范围内使用及复用
2. 符合最小暴露原则
3. 应用:任意代码片段外部添加函数包装,可以将内部的变量 和 函数 隐藏起来

3. 函数声明 函数表达式

  1. 函数声明:被绑定在所在的作用域中,可直接调用

    function foo() {}
    
  2. 函数表达式:变量隐藏

    (function foo() {});
    
  3. 匿名函数表达式

    setTimeout(function() {}, 1000);
    

    缺点:

    1. 栈追踪不会现实出有意义的函数名
    2. 引用自身需要用 arguments.call 3. 可读性差
  4. 行内函数表达式

    setTimeout(function foo() {}, 1000);
    
  5. 立即执行函数表达式(IIFE)

    // 第一种:
    (function() {})();
    
    // 第二种:
    (function() {})();
    

    应用:

    1. window 引用传递。对全局变量更加清晰
    2. 防止 undefined 默认值被错误覆盖
    3. UMD 函数当参数传递进来
    (function IIFE(def) {
        def(window);
    })(function def(global) {
        var a = 3;
        console.log(a); // 2
        console.log(global.a); // 2
    });
    

4. 块级作用域

1. with 创建对是块级作用域

2. try/catch 中 catch(e){} 中对 e 就是一个会计作用域变量,仅在catch内部有效

3. let
    1. 隐式的劫持了所在的块级作用域
    2. 不会在块级作用域中提升
    3. 为变量显示的声明块级作用域 有时候会 提高代码效率
     这里的举例 很有意思

4. const

More

  1. var 函数作用域
  2. let const 块级作用域