Web高级 - 05 作用域&作用域链(闭包的形成)

    技术2022-07-10  115

    创建函数时:

    创建一个堆( 存储代码字符串和对应的键值对 )

    初始化当前函数的作用域( [[scope]] = 所在上下文中的变量对象VO/AO )

    执行函数时:

    创建一个新的执行上下文EC( 压缩到ECStack里执行)

    初始化this指向

    初始化作用域链[[scopeChain]] 

    创建AO变量对象用来存储变量 => arguments => 形参 => 代码执行

    this指向/执行主体:谁把他执行的

    第1种:函数执行,看前面是否有".",

    有:"."前面是谁this就是谁  fn() this:window

    无:this是window(严格模式下是undefined),自执行函数的this一般都是window   

    obj.fn()   this:obj             obj.__proto__.fn()    this:obj.__proto__    

    第2种:给元素的事件行为绑定方法(DOM0/DOM2),事件触发,方法会执行,此时方法中的this一般都是当前元素本身

    box.onclick = function(){  // => this:box  }

    box.addEventListener("click", function(){  // => this:box  }) 

    特殊情况,IE8及以下,基于attachEvent完成DOM2事件绑定,this是不准确的

    box.attachEvent("onclick",function(){  // => this:window  })

     

    面试题:

    1、

    function A(y){ let x = 2; function B(z){ console.log(x+y+z); } return B; } let c = A(2); C(3);

    2、

    let x = 5; function fn(x){ return function(y){ console.log(y + (++x)); } } let f = fn(6); f(7); // 14 fn(8)(9); // 18 f(10); // 18 console.log(x); // 5

    3、

    let x = 5; function fn(){ return function(y){ console.log(y + (++x)); } } let f = fn(6); f(7); // 13 fn(8)(9); // 16 f(10); // 18 console.log(x); // 8

    4、

    let a = 0, b = 0; function A(a){ A = function(b){ console.log(a+b++); } console.log(a++); } A(1); //1 A(2); //4

    5、

    var x = 3, obj = { x : 5 }; obj.fn = (function(){ this.x *= ++x; return function (y){ this.x *= (++x)+y; console.log(x); } })(); var fn = obj.fn; //13 obj.fn(6); //234 fn(4); //95 console.log(obj.x,x); //234

     

    Processed: 0.032, SQL: 9