創建函數時:
創建一個堆( 存儲代碼字符串和對應的鍵值對 )
初始化當前函數的作用域( [[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