javascript中this指向的理解(轉載)
JS中的this指向一直是個讓人頭疼的問題,想當初我學的是天昏地暗,查了好多資料,看的頭都大了,跟他大戰了那麼多回合,終於把它搞定個七八分,其實往往都是我們複雜化了,現在就讓大家輕鬆看懂this的指向,我會分以下幾種情況來說。
this的指向:
1 this 指的是直接呼叫當前方法(函式)的那個物件,也就是說函式在誰那被呼叫,this就指的是誰。
來看兩個栗子:
oBtn.onclick = function(){ alert(this); //oBtn } oBtn.onclick= fn1; function fn1(){ alert(this); //oBtn }
很容易看出,函式是在按鈕物件被點選的時候呼叫,所以this指的是obtn,這兩種情況是等同的是,只是呼叫函式的寫法不同。
2 當函式裡面巢狀函式的時候,巢狀的那個函式裡面的this指的是window,不要過分深究這個原因,因為這是JS的一個特性。
來看個栗子:
oBtn.onclick = function(){ alert(this); //oBtn(記得這裡還是oBtn) fn1(); }function fn1(){ alert(this); // window }
對於上述情況,當我們需要fn1裡面的this指向按鈕的時候怎麼辦呢,這個時候有兩種方法。
1 將this作為引數傳函式去
2 將this儲存起來賦給另一個變數
來看兩個栗子:
1 oBtn.onclick = function(){ alert(this); //oBtn fn1(this); 1 將上面的this作為引數傳函式去 } function fn1(obj){ alert(obj);// oBtn } 2 var that = null; oBtn[i].onclick = function(){ alert(this); //oBtn that = this ;// 將上面的this儲存起來賦給另一個變數 fn1(); } function fn1(){ alert(that); // 指向oBtn }
$("#btn").click(function () { var _this = this;//這裡this和_this都代表了"#btn"這個物件 $(".tr").each(function () { this;//在這裡this代表的是每個遍歷到的".tr"物件 _this;//仍代表"#btn"物件 }) })
後續補充:
3 如果有new關鍵字,this指向new出來的那個物件;
當用new去呼叫一個函式:這個時候this指的就是創建出來的物件 而且函式的預設返回值就是this 即這個物件(隱式返回 不用自己再寫返回值)
function CreatePerson(name){ //函式名首字母大寫 //var this=new Object(); 系統會偷偷在這裡宣告一個物件賦給this替咱們做,不用寫 this.name = name; this.showName = function(){ alert(this.name); } //return this; 函式的預設返回值就是this即這個物件(隱式返回 不用自己再寫返回值) } var p1 =new CreatePerson('haha'); //當用new去呼叫一個函式:這個時候this指的就是創建出來的物件 而且函式的預設返回值就是this即這個物件(隱式返回 不用自己再寫返回值) p1.showName();
new操作符具體幹了什麼呢?
(1)建立一個空物件,並且 this 變數引用該物件,同時還繼承了該函式的原型。
(2)屬性和方法被加入到 this 引用的物件中。
(3)新建立的物件由 this 所引用,並且最後隱式的返回 this 。
4 在IE下,事件的繫結的第二種形式中,obj.attachEvent(事件名稱,事件函式),裡面的this指的是window。
當然這不是我們想要的,所以讓this指向觸發事件的物件呢?這就需要提到一個方法call();它可以改變this的指向
call(this的指向,原來函式的引數列表):它有兩個引數,第一個指的是改變的this的指向,也就是你想要this指向誰就寫誰,如果寫的是null,this的指向就不會改變,還是指向原來的。從第二個引數開始,就代表的是函式裡面的具體傳入的引數了。具體用法我們來看個栗子:
//有一個函式,兩個引數。 function fn1(a,b){ alert(this); // 本來預設是window,改變後為1 alert(a+b);// 30 } //三種呼叫方法 fn1(); //正常呼叫。彈出 this指向window, a+b為 undefined fn1.call(); // 等同於上面 ,這兩種呼叫是一樣的 fn1.call(1,10,20); // 彈出this指向 1,同時傳入兩個數,彈出30
改變this指向是不是也很簡單呢。。。。。。