前端編程對於this再熟悉不過了,今日來個老調重彈溫故知新,確定有不少大佬已經徹底吃透了this原理,敬請出門左拐。對於理解this似懂非懂的同窗能夠借鑑一波html
this指的是當前執行環境上下文,只要緊緊抓住這一點就能找到this的根源,this.function、this.property就能準肯定位實際對象。前端
window 綁定編程
function sayAge () { console.log(this.age); } var user = { name: 'ccy', age: 18 } sayAge()
輸出結果爲undefined,仔細思考當前函數執行的上下文,其實等價於window.sayAge()數組
this默認綁定在window全局對象上app
function foo() { console.log( this.a ); } var obj = { a: 2, foo: foo }; obj.foo();
這段代碼this綁定到了obj對象,當函數引用有上下文對象(context)時,隱式綁定規則會把this綁定到這個上下文對象函數
再看看隱式丟失問題post
var bar=obj.foo; bar();
輸出undefined,由於此時執行上下文爲全局對象,沒有a屬性this
顯式綁定spa
在分析隱式綁定時,必須將函數做爲對象的屬性,從而將此對象綁定在函數的執行上下文,但想一想是否是很麻煩,顯示綁定可解決此問題。prototype
function foo() { console.log( this.a );
} var obj = { a:2 }; foo.call( obj );
用函數原型屬性 call、apply、bind均可以實現
Function.prototype.call=function(ctx,arg1,arg2,/*...*/argN){native code} Function.prototype.apply=function(ctx,arrys){native code} Function.prototype.bind=function(ctx){native code}
固然這些函數原型屬性均可以重寫以實現本身的需求,call和apply的區別僅僅在於第二個參數開始apply傳遞數組,call是將參數一個個傳遞,call與bind的區別在於bind不能當即執行。
其實每當用 new 調用函數時,JavaScript 解釋器都會在底層建立一個全新的對象並把這個對象當作 this。若是用 new 調用一個函數,this 會天然地引用解釋器建立的新對象。
function User (name, age) { /* JavaScript 會在底層建立一個新對象 `this`,它會代理不在 User 原型鏈上的屬性。 若是一個函數用 new 關鍵字調用,this 就會指向解釋器建立的新對象。 */ this.name = name this.age = age } var me = new User('ccy', 18)
若是要判斷一個運行中函數的this綁定,就須要找到這個函數的直接調用位置。找到以後就能夠順序應用下面這四條規則來判斷this的綁定對象。