JavaScript中的this總是讓人迷惑,應該是js眾所周知的坑之一。 個人也覺得js中的this不是一個好的設計,由於this晚綁定的特性,它可以是全域對象,當前對象,或者…有人甚至因為坑大而不用this。其實如果完全掌握了this的工作原理,自然就不會走進這些坑。來看下以下這些情況中的this分別會指向什麼:
1.全域代碼中的this
alert(this)//window
全域範圍內的this將會指向全域對象,在瀏覽器中即使window。
2.作為單純的函數調用
functionfooCoder(x) { this.x = x;}fooCoder(2);alert(x);// 全域變數x值為2
這裡this指向了全域對象,即window。在strict 模式中,則是undefined。
3.作為對象的方法調用
varname = "clever coder";varperson = { name : "foocoder", hello : function(sth){ console.log(this.name + " says "+ sth); }}person.hello("hello world");
輸出 foocoder says hello world。this指向person對象,即當前對象。
4.作為建構函式
newFooCoder();
函數內部的this指向新建立的對象。
5.內建函式
varname = "clever coder";varperson = { name : "foocoder", hello : function(sth){ varsayhello = function(sth) { console.log(this.name + " says "+ sth); }; sayhello(sth); }}person.hello("hello world");//clever coder says hello world
在內建函式中,this沒有按預想的綁定到外層函數對象上,而是綁定到了全域對象。這裡普遍被認為是JavaScript語言的設計錯誤,因為沒有人想讓內建函式中的this指向全域對象。一般的處理方式是將this作為變數儲存下來,一般約定為that或者self:
varname = "clever coder";varperson = { name : "foocoder", hello : function(sth){ varthat = this; varsayhello = function(sth) { console.log(that.name + " says "+ sth); }; sayhello(sth); }}person.hello("hello world");//foocoder says hello world
6.使用call和apply設定this
person.hello.call(person, "world");
apply和call類似,只是後面的參數是通過一個數組傳入,而不是分開傳入。兩者的方法定義:
call( thisArg [,arg1,arg2,… ] ); // 參數列表,arg1,arg2,...apply(thisArg [,argArray] ); // 參數數組,argArray
兩者都是將某個函數綁定到某個具體對象上使用,自然此時的this會被顯式的設定為第一個參數。
查看本欄目更多精彩內容:http://www.bianceng.cnhttp://www.bianceng.cn/webkf/script/