• JS学习梳理(一)作用域和闭包


    1. 编译特点:实时编译、执行。性能保证:JIT、延迟编译、重编译
    2. 编译构成
      • 引擎
      • 编译器
      • 作用域
    3. 执行顺序:编译阶段 -> 执行阶段
      • 编译阶段:函数声明和变量声明都会被提升
      • 编译阶段:函数提升先于变量
      • 编译阶段:同名函数或变量会被覆盖
    4. 欺骗词法(非严格模式)
      • eval('str'),性能低
      • with,未找到匹配属性时,易自动创建成全局变量
    5. 函数作用域和块作用域
      • 立即执行函数
        (function foo() {})();
      • let(ES6),块作用域
        {
          console.log( bar ); // ReferenceError!
          let bar = 2;
        }
        function process(data) {
        // 在这里做点有趣的事情
        }
        // 在这个块中定义的内容可以销毁了!
        {
            let someReallyBigData = { .. };
            process( someReallyBigData );
        }
        var btn = document.getElementById( "my_button" );
        btn.addEventListener( "click", function click(evt){
        console.log("button clicked");
        }, /*capturingPhase=*/false );
      • const(ES6),块作用域,被修改后会报错
    6. 闭包
      //我们对这段代码行为的预期是分别输出数字1~5,每秒一次,每次一个。但实际上,这段代码在运行时会以每秒一次的频率输出五次6
      for
      (var i=1; i<=5; i++) { setTimeout( function timer() { console.log(i); }, i*1000 ); }

      //修改之后,通过立即执行函数来创建作用域。注意i,j之间的值传递。
      for (var i=1; i<=5; i++) {
      (function(j) {
      setTimeout( function timer() {
      console.log(j);
      }, j*1000 );
      })(i);
      }

      //for 循环头部的let 声明还会有一个特殊的行为。这个行为指出变量在循环过程中不止被声明一次,每次迭代都会声明。随后的每个迭代都会使用上一个迭代结束时的值来初始化这个变量。
      for (let i=1; i<=5; i++) {
      setTimeout( function timer() {
      console.log( i );
      }, i*1000 );
      }
    7. 模块
      • 最常见的实现模块模式的方法通常被称为模块暴露
      • ES6 的模块没有“行内”格式,必须被定义在独立的文件中(一个文件一个模块)
    8. 动态作用域
      • JavaScript 并不具有动态作用域,它只有词法作用域,但是this 机制某种程度上很像动态作用域
      • 主要区别:词法作用域是在写代码或者说定义时确定的,而动态作用域是在运行时确定的。(this 也是!)词法作用域关注函数在何处声明,而动态作用域关注函数从何处调用。
    9. 其他
      • Google 维护着一个名为Traceur 的项目,用来将ES6 代码转换成兼容ES6 之前的环境。
      • “胖箭头”
        var obj = {
            count: 0,
            cool: function coolFn() {
                if (this.count < 1) {
                    setTimeout(() => { // 胖箭头语法
                        this.count++;
                        console.log("awesome?");
                    }, 100);
                }
            }
        };
        obj.cool(); // awesome?
      • bind
        var obj = {
            count: 0,
            cool: function coolFn() {
                if (this.count < 1) {
                    setTimeout(function timer() {
                        this.count++; // this 是安全的
                        // 因为bind(..)
                        console.log("more awesome");
                    }.bind(this), 100); // look, bind()!
                }
            }
        };
        obj.cool(); // more awesome
  • 相关阅读:
    【BZOJ4033】【HAOI2015】树上染色
    【BZOJ1040】【ZJOI2008】骑士
    【BZOJ3573】【HNOI2014】米特运输
    【BZOJ1060】【ZJOI2007】时态同步
    17-10-11模拟赛
    17-10-05模拟赛
    17-09-29模拟赛
    17-09-21模拟赛
    17-09-20模拟赛
    17-09-15模拟赛
  • 原文地址:https://www.cnblogs.com/chenjunsheep/p/8678582.html
Copyright © 2020-2023  润新知