1. 知識點
匿名函數無法從函數內部應用自身
this 是在運行時進行綁定的,並不是在編寫時綁定,它的上下文取決於函數調用時的各種條件。this 的綁定和函數聲明的位置沒有任何關係,只取決於函數的調用方式。
當一個函數被調用時,會創建一個活動記錄(有時候也稱爲執行上下文)。這個記錄會包含函數在哪裏被調用(調用棧)、函數的調用方法、傳入的參數等信息。this 就是記錄的其中一個屬性,會在函數執行的過程中用到。
this簡單講就是:調用我的"人"在什麼上下文環境,我就指向誰!!
2. 題目:
var number = 2;
var obj = {
number: 4,
fn1: (function () {
var number;
this.number *= 2;
number = number * 2;
number = 3;
return function () {
var num = this.number;
this.number *= 2;
console.log(num);
number *= 3;
console.log(number);
};
})(),
db2: function () {
this.number *= 2;
},
};
var fn1 = obj.fn1;
var fn2 = obj.db2;
console.log(number);
fn1();
fn2();
obj.fn1();
obj.db2();
console.log(window.number);
console.log(obj.number);
3. 執行過程
var fn1 = obj.fn1;
fn1
在全局執行,this 指向全局
var number = 2;
var obj = {
number: 4,
fn1: (function () {
var number;
this.number *= 2; // 指向全局變量number number=4
number = number * 2;
number = 3; // 函數內number = 3
return function () {
var num = this.number;
this.number *= 2;
console.log(num);
number *= 3;
console.log(number);
};
})(),
db2: function () {
this.number *= 2;
},
};
var fn2 = obj.db2;
fn2
中的 this 指向全局變量
console.log(number)
打印全局變量 number
輸出 ‘4’
fn1()
this 指向全局
var number = 2;
var obj = {
number: 4,
fn1: (function () {
var number;
this.number *= 2; //全局number=4
number = number * 2; //NAN
number = 3; //函數內number = 3
return function () {
var num = this.number; //全局作用域 num=4
this.number *= 2; // 全局number = 8
console.log(num); // 輸出4
number *= 3; // 函數內number 3*3=9(形成閉包)
console.log(number); // 輸出9
};
})(),
db2: function () {
this.number *= 2;
},
};
fn2()
this 指向全局
var number = 2;
var obj = {
number: 4,
fn1: (function () {
var number;
this.number *= 2;
number = number * 2;
number = 3;
return function () {
var num = this.number;
this.number *= 2;
console.log(num);
number *= 3;
console.log(number);
};
})(),
db2: function () {
this.number *= 2; //全局number = 8 8*2=16
},
};
obj.fn1()
這裏執行時 執行環境是 obj,所以 this 指向 obj
this.number = obj.number
number 則是形成閉包,調用上次的值
var number = 2;
var obj = {
number: 4,
fn1: (function () {
var number;
this.number *= 2;
number = number * 2;
number = 3;
return function () {
var num = this.number; // obj.number=this.number=num=4
this.number *= 2; // obj.number =4*2=8
console.log(num); // 打印 num=4
number *= 3; //閉包 number=9*3=27
console.log(number); // 打印 number=27
};
})(),
db2: function () {
this.number *= 2;
},
};
obj.db2()
this
指向obj
var number = 2;
var obj = {
number: 4,
fn1: (function () {
var number;
this.number *= 2;
number = number * 2;
number = 3;
return function () {
var num = this.number;
this.number *= 2;
console.log(num);
number *= 3;
console.log(number);
};
})(),
db2: function () {
this.number *= 2; // obj.number=this.number=8*2=16
},
};
console.log(window.number)
打印 16
console.log(obj.number)
打印 16
參考鏈接
-
你不知道的 JavaSctript(上卷)