這又是一個面試經典問題~/(ㄒoㄒ)/~~也是 ES5中眾多坑中的一個,在 ES6 中可能會極大避免 this 產生的錯誤,但是為了一些老代碼的維護,最好還是了解一下 this 的指向和 call、apply、bind 三者的區別。
this 的指向
在 ES5 中,其實 this 的指向,始終堅持一個原理:this 永遠指向最后調用它的那個對象,來,跟著我朗讀三遍:this 永遠指向最后調用它的那個對象,this 永遠指向最后調用它的那個對象,this 永遠指向最后調用它的那個對象。記住這句話,this 你已經了解一半了。
下面我們來看一個最簡單的例子:
例 1:
var name = "windowsName"; function a() { var name = "Cherry"; console.log(this.name); // windowsName console.log("inner:" + this); // inner: Window } a(); console.log("outer:" + this) // outer: Window這個相信大家都知道為什么 log 的是 windowsName,因為根據剛剛的那句話“this 永遠指向最后調用它的那個對象”,我們看最后調用 a 的地方 a();,前面沒有調用的對象那么就是全局對象 window,這就相當于是 window.a();注意,這里我們沒有使用嚴格模式,如果使用嚴格模式的話,全局對象就是 undefined,那么就會報錯 Uncaught TypeError: Cannot read property 'name' of undefined。
再看下這個例子:
例 2:
var name = "windowsName"; var a = { name: "Cherry", fn : function () { console.log(this.name); // Cherry } } a.fn();在這個例子中,函數 fn 是對象 a 調用的,所以打印的值就是 a 中的 name 的值。是不是有一點清晰了呢~
我們做一個小小的改動:
例 3:
var name = "windowsName"; var a = { name: "Cherry", fn : function () { console.log(this.name); // Cherry } } window.a.fn();這里打印 Cherry 的原因也是因為剛剛那句話“this 永遠指向最后調用它的那個對象”,最后調用它的對象仍然是對象 a。
我們再來看一下這個例子:
例 4:
var name = "windowsName"; var a = { // name: "Cherry", fn : function () { console.log(this.name); // undefined } } window.a.fn();這里為什么會打印 undefined 呢?這是因為正如剛剛所描述的那樣,調用 fn 的是 a 對象,也就是說 fn 的內部的 this 是對象 a,而對象 a 中并沒有對 name 進行定義,所以 log 的 this.name 的值是 undefined。
這個例子還是說明了:this 永遠指向最后調用它的那個對象,因為最后調用 fn 的對象是 a,所以就算 a 中沒有 name 這個屬性,也不會繼續向上一個對象尋找 this.name,而是直接輸出 undefined。
再來看一個比較坑的例子:
例 5:
var name = "windowsName"; var a = { name : null, // name: "Cherry", fn : function () { console.log(this.name); // windowsName } } var f = a.fn; f();這里你可能會有疑問,為什么不是 Cherry,這是因為雖然將 a 對象的 fn 方法賦值給變量 f 了,但是沒有調用,再接著跟我念這一句話:“this 永遠指向最后調用它的那個對象”,由于剛剛的 f 并沒有調用,所以 fn() 最后仍然是被 window 調用的。所以 this 指向的也就是 window。
由以上五個例子我們可以看出,this 的指向并不是在創建的時候就可以確定的,在 es5 中,永遠是this 永遠指向最后調用它的那個對象。
再來看一個例子:
例 6:
var name = "windowsName"; function fn() { var name = 'Cherry'; innerFunction(); function innerFunction() { console.log(this.name); // windowsName } } fn()讀到現在了應該能夠理解這是為什么了吧(o゚ 主站蜘蛛池模板: 三门峡市| 隆子县| 万宁市| 灵璧县| 西平县| 铜梁县| 调兵山市| 阜宁县| 嘉义县| 临泉县| 沈阳市| 桐柏县| 德令哈市| 轮台县| 五大连池市| 阿拉善右旗| 凤凰县| 麻城市| 永嘉县| 德令哈市| 驻马店市| 芜湖市| 延川县| 应城市| 乐至县| 鱼台县| 金寨县| 伊川县| 通山县| 宁化县| 乌审旗| 凌海市| 肥东县| 缙云县| 子长县| 和林格尔县| 五台县| 桦川县| 田林县| 比如县| 旬邑县|