這篇文章主要介紹了對JavaScript中this指標的新理解分享,本文講解了方法呼叫模式、函數呼叫模式、建構子呼叫模式、Apply呼叫模式中的this指針理解,需要的朋友可以參考下
一直以來對this的理解只在可以用,會用,卻沒有去深究其本質。這次,藉著《JavaScript The Good Parts》,作了一次深刻的理解。 (所有調試都可以在控制台中看到,瀏覽器F12鍵)
下面我們一起來看看這個this吧。
在我們宣告一個函數時,每個函數除了有定義時的parameters(形參),自身還會有額外的兩個參數,一個是this,一個是arguments(實參)。 arguments就是函數實際接受到的參數,是一個類別數組。 arguments我只做個簡略的介紹,重點我們放在this指針上。
在物件導向變成中,this十分重要,它的值取決於呼叫的模式。而在JavaScript中,總共有4個呼叫模式:方法呼叫模式、函式呼叫模式、建構函式呼叫模式、apply呼叫模式。
方法呼叫模式
當一個函數是作為一個物件的屬性時,我們通常稱這個函數為這個物件的一個方法。當這個方法被呼叫時,this就會指向該方法所屬物件。
程式碼如下:
<script type="text/javascript"> var people = { name : "Yika", sayName : function(){ console.log(this.name); //"Yika" //this已经绑定在了people对象上了 } } people.sayName(); </script>
如栗子所示,this指向了sayName對象,這種透過this取得所屬物件上下文的方法,就是公共方法。 (publice method)
函數呼叫模式
當一個函數被呼叫時並非某個物件上的方法,那麼它就是作為一個函數被呼叫的。
這種模式調用,this會指向window物件,即使這個函數或許是在外部函數裡調用的,我們來看栗子。
程式碼如下:
<script type="text/javascript"> var name = "window-Yika"; var people = { name : "people-Yika", student : function(){ console.log(this); //这里的this绑定的是对象people function sayName(){ var name = "sayName-Yika"; console.log(this.name); //window-Yika //即使sayName函数本身和它所在的people对象都有name值,但是this是指向window的 }; sayName(); } } people.student(); </script>
這樣一看,大概知道該怎麼解決JavaScript這個「設計錯誤」了呢。
是的只要在student函數裡面,也就是第6行,將this快取起來。然後再將this透過變數轉移到sayName函數裡就可以解決啦!
程式碼如下:
var people = { name : "people-Yika", student : function(){ var self = this; //将this缓存起来 function sayName(){ var name = "sayName-Yika"; console.log(self.name); //"people-Yika",此时的self指向的是people对象 }; sayName(); } }
建構函數呼叫模式
# JavaScript裡一講到建構函數,腦海裡就會有:「函數名稱大寫!可是你有沒有深究過為什麼要用new?如果在一個函數前面帶上new來調用,那麼函數後台會建立一個指向該函數prototype的新對象,同時this也綁定在新對像上。 JavaScript是基於原型繼承的語言,對原型prototype不是很清楚的同學可以自己去查一下資料,我重點放在this上面。 我們先來看看建構函式一般長什麼樣子。
程式碼如下:<script type="text/javascript"> function People(name){ this.name = name; //这里的this,用new调用后便指向了新对象Yika this.sayName = function(){ console.log(this.name); //输出 } } var Yika = new People("Yika"); Yika.sayName(); //输出“Yika" ,因为Yika是通过new调用得来的,this都绑定在了Yika对象上。 </script>
沒關係,剛才不是說函數透過new調用,會在背地裡自己做「做壞事」麼,我們一起看看到底做了哪些事。
程式碼如下:<script type="text/javascript"> function People(name){ var that = {}; //坏事一:自己生成一个对象 that.name = name; that.sayName = function(){ console.log(that.name); }; return that; //坏事二,自己会改变return的行为,return刚生成的对象 } var Yika = People("Yika"); //这里可以省略new,模仿调用new操作符 Yika.sayName(); //和刚才一样输出"Yika" </script>
千萬記得要用 new 呼叫建構函數,不然出了問題,是沒有警告的,所有大寫約定還是十分有必要的。
Apply呼叫模式apply方法讓我們建立一個參數陣列傳遞給呼叫函數,也允許我們改變this值。
function.apply(this綁定的值, arguments參數數組)
apply可以說的東西太多了,我這裡只舉個的栗子來幫助大家理解:
程式碼如下:
<script type="text/javascript"> function People(name){ this.name = name; this.sayName = function(){ console.log(this.name); //sayName这个方法是属于People构造函数的 } } function Student(name){ People.apply(this, arguments);//借用构造函数的集成方式,就是在Student构造函数里,通过apply调用People构造函数,并改变People的this值 //这样每次创建Student实例时,都会调用People构造函数 } var student = new Student("Yika"); student.sayName(); //输出“Yika” </script>
我們可以透過apply輕易的修改函數的this綁定對象,和apply相似的方法call也有一樣的效果,有興趣的同學可以自己搜尋學習一下。
好了,總算講完改變this的四種呼叫模式了,方法呼叫模式和建構子呼叫模式會用的更多,也會更重要一點,而函數呼叫模式,我們則要學會避開其中的陷阱。
若有錯誤,請及時反映,我會盡快糾正,以防誤導他人,謝謝!
以上是JavaScript中對this指針的新理解的詳細內容。更多資訊請關注PHP中文網其他相關文章!