說this是js程式設計中最重要的變數也不為過了,而在遇到this時,也曾經傻傻分不清楚this指代的到底是什麼,所以現在對曾踩過this的坑做一下總結(注:本文中的this值適用場景為執行環境為瀏覽器時,執行環境為node時會有不同表現)。
雖然this很令人迷惑,但其實總會發現,在瀏覽器環境中,this的指代不外乎兩種,要麼是window,要麼是某個特定的物件(window之外的物件),而涉及到具體的場景中this的取值,可以歸納為五種。
var global=4;
console.log(this.global);
複製**
如上例中,在全域性作用域下定義了變數global,同樣的,當我們呼叫this.global時,會把之前定義的變數列印出來。這是因為,全域性作用域中定義的變數相當於為window物件新增了屬性,而全域性作用域下直接呼叫this,同樣指代了window物件,因此能夠取到之前定義的this值。
物件方法,也即物件的成員函式,物件方法中的this指代的是物件本身。
var obj=
}複製**
如上例中obj是乙個物件,value和func分別為它的成員變數和成員方法,此時在方法中取到的this.value值即為obj.value值,this指代的是obj本身。
new操作符通常和建構函式共同出現,往往用於建立乙個新物件,而此時建構函式中的this指代的正是所建立的新物件。
function
car()
}var car=new car();
console.log(car.getcolor())//red
複製**
如上例所示,這裡可以正確的把red列印出來,其中函式car是乙個最基本的建構函式,當用new 操作符來建立乙個新的color物件時,建構函式執行過程中首先會新建乙個物件,然後將this賦值給這個新物件,之後所有對this的賦值操作都等同於對新物件賦值了。
在呼叫普通函式表示式時,呼叫this,往往指代的是window物件。
var value=3;
var func=function
()func();
複製**
如上所示,func是乙個普通的指代函式的變數,在該函式中呼叫this,指代的是window物件。
var obj=
}var func=obj.getvalue;
console.log(func());
複製**
看到上例,可能會毫不猶豫的說答案當然是3了,很簡單嘛,obj.getvalue,所屬物件是obj,裡面的this指代的當然是obj了,返回的this.a當然就是obj.a,是3沒問題,這時候,看了控制台的列印就會大吃一驚了,答案是undefined,這是因為var func=obj.getvalue這一句賦值語句被忽略了,但這是至關重要的,經過這個賦值語句之後,this指代的不再是obj本身了,而是全域性物件window,因為wiondow中不含有a變數,this.a當然是undefined了。
var obj=
return innerfunc();
}}console.log(obj.func());
複製**
看到這裡,可能又會脫口而出,列印出的值是4沒錯,這次明顯就是直接呼叫的obj物件的func函式,this總該指向obj了吧,但是當然了,答案依然是undefined,不要忽略,getvalue函式中this是經過innerfunc呼叫的,而innerfunc的呼叫物件並不是obj,所以在執行innerfunc函式時,其中的this是指代window的,a值是undefined。
以上的題目二之所以迷惑我們,關鍵的一點是,有時候不自覺得將this和作用域關聯起來,因此,不要將this和作用域等同,不要自然而然的找innerfunc中的this時,會去找其包含作用域getvalue的this,因為每個函式天生就有this變數,所以某個函式本身的this與其包含作用域中的this無直接關係。
有了以上的五種場景和常見的兩個this題目坑,或許可以作如下總結,this的指代值只有兩種:
呼叫函式表示式的值或直接呼叫函式表示式時,this是window 直接呼叫函式表示式或其值的場景也有很多,如
var a=function
()a();//呼叫函式表示式的值
(function
())();//呼叫函式表示式
~~function
()();//呼叫函式表示式;
複製**
第一節中提到的全域性作用域中的this也可以等同於在乙個全域性函式中呼叫,this,是window. 有了以上兩種判斷方法就會更簡單了,甚至只要區分出一種場景,就能快速判斷了,如只要確定this所在的函式指定(繫結)了呼叫物件,this就相當於該物件,否則就是window.
上述的兩個坑只是稍微列舉了一下,實際開發中this的坑真的很多,尤其對我這種小白來說,總結發現this的這麼多坑的原因往往與乙個特性有關,就是this的後繫結,在看到涉及this的函式定義時,往往不自覺的在這裡就給this賦值了,如上節中的坑一,正因為我看到的this所在的函式是屬於乙個物件的,所以未理會var func=obj.getvalue,變不由得將this和obj繫結了,但這種明顯是錯誤的,由於this的後繫結,我們不應隨意在看到this時就將其賦值,而應好好分析在呼叫時this的所指才是正解。 那麼為什麼this要後繫結呢,給我們帶來了這麼多坑,這應該設計到語言的設計問題了,這裡無法深入,但毋庸置疑的是,js的極其重要的原型繼承機制就是依賴於this後繫結的,想象一下this不是後繫結,後果很可怕。。。。
棄坑pexpect,入坑paramiko
上文書說到,ssh庫pexpect的使用,簡直就是個 月亮公主 滿眼全是坑。勉強把程式寫好了,跑起來的時候發現了乙個新坑,讓我不可抗拒的把它棄掉了 經常莫名其妙的連不上伺服器!開執行緒連線14臺伺服器,總有1到3臺連不上,還查不到原因。這還了得!一怒之下把寫好的pexpect封裝庫刪掉了,用para...
棄 填坑計畫 1 (2016 03 06)
演算法學習 1 tarjan演算法 已完成 2016.04.03 2 費用流 已完成 2016.04.07 3 字尾自動機 已完成 2016.03.10 4 旋轉卡殼 5 cdq分治 複習演算法 1 splay 已完成 2016.03.23 2 kmp 3 莫隊演算法 4 主席樹 學習樹狀陣列套主席...
javascript之踩坑記錄
console.log true console.log false 這個坑在於js裡的 和 的區別。1 對於string,number等基礎型別,和 是有區別的 1 不同型別間比較,之比較 轉化成同一型別後的值 看 值 是否相等,如果型別不同,其結果就是不等 2 同型別比較,直接進行 值 比較,兩...