JS中this和物件作為函式引數的區別
一個簡單的例子
要求:
1、一個列表有一些簡單的包含文字的行
2、滑鼠移到某一行上時背景色改為色值為 #f2f2f2,移開滑鼠時則恢復為原背景色 #fff
3、點選新增按鈕,能動態在最後新增一行
提示
- 獲取表格的行,getElementsByTagName 。
- 使用for進行迴圈,為每行新增事件及背景顏色設定
<script type="text/javascript">
//頁面初始化的過程幫已存在的每一行新增繫結
window.onload = function(){
//滑鼠移動改變背景,可以通過給每行繫結滑鼠移上事件和滑鼠移除事件來改變所在行背景色。
for(i=1;i<document.getElementsByTagName("tr").length;i++) {
//程式還有動態新增行數的功能,所以最好給每行繫結滑鼠事件獨立出來作為一個函式。
//等下動態新增的行直接呼叫下面的函式就能實現繫結,而不用全部重新進行初始化繫結。
highLight(document.getElementsByTagName("tr")[i]);
}
}
//highLight函式用來繫結滑鼠事件
如何編寫highLight函式
第一種做法
function highLight (obj) {
obj.setAttribute("onmouseover","over(obj)");
obj.setAttribute("onmouseout","out(obj)");
}
//這裡給傳遞過來的物件obj設定背景
function over(obj) {
obj.style.backgroundColor="#ccc";
}
function out(obj) {
obj.style.backgroundColor="#fff";
}
以上的程式是給傳遞過來的物件obj設定onmouseover和onmouseout屬性(和over以及out函式繫結),並將這個物件obj再繼續傳遞給over和out函式去改變背景。
然而以上做法是錯誤的
我們在highLight()函式中幫表中的每一行的”onmouseover”屬性綁定了”over(obj)”。這時候這個obj是初始化函式傳遞過來的,引數又是區域性變數,程式執行結束之後就會刪除這個物件引數。當我們再一次將滑鼠移到表中,每一行的onmouseover屬性就會呼叫over(obj),這個時候已經不知道obj是誰了。
第二種做法
我們需要使用this關鍵字:
function highLight(obj) {
obj.setAttribute("onmouseover","over(this)");
obj.setAttribute("onmouseout","out(this)");
}
function over(obj) {
obj.style.backgroundColor="#ccc";
}
function out(obj) {
obj.style.backgroundColor="#fff";
}
這個時候函式是可行的。
在highLight(obj)函式是在頁面載入階段就執行結束了,這個時候就把onmouseover屬性和over(this)繫結。滑鼠移動到那一行觸發onmouseover接著呼叫了over()函式,並把this也就是目前的物件傳遞過去執行函式。
而第一個例子highLight(obj)函式把自己的obj引數傳遞給over()函式,這個obj物件只在hightLigt()函式執行時有效。之後觸發onmouseover執行over(obj)時,over函式想呼叫obj物件的進行設定,可是這個時候obj物件早就不見了。
如下程式也是同樣的道理
function highLight(obj) {
obj.setAttribute("onmouseover" ,"obj.style.backgroundColor='#ccc'");
obj.setAttribute("onmouseout" , "obj.style.backgroundColor='#fff'");
}
同樣觸發了onmouseover便會觸發設定,這個時候已經不知道obj是什麼了。
function highLight(obj) {
obj.setAttribute("onmouseover" , "this.style.backgroundColor='#ccc'");
obj.setAttribute("onmouseout" , "this.style.backgroundColor='#fff'");
}
這裡的this表示一個呼叫了屬性設定函式的物件,這個物件便是highLight(obj)函式的引數obj;所以每個obj都將onmouseover屬性和他自身的backgroundColor賦值操作繫結。每次觸發都會呼叫被觸發的物件進行屬性設定,而不是像之前呼叫highLight函式傳遞過來的物件。故這種方法也是正確的。
總結
一、引數物件的生命週期就只在函式被呼叫的時候存在,所以在單次操作例如給物件設定某個屬性的時候使用。例如obj.setAttribute(),這個物件屬性設定就可以用obj。
二、this代表著某個行物件,每次滑鼠移過去,觸發了這個行物件的onmouseover,就呼叫over(this)函式,這個時候將自身作為引數傳遞過去改變屬性。