JavaScript之this詳解

蟹丸發表於2018-11-30

前言

前端程式設計對於this再熟悉不過了,今日來個老調重彈溫故知新,肯定有很多大佬已經完全吃透了this原理,敬請出門左拐。對於理解this似懂非懂的同學可以借鑑一波

1.this描述

this指的是當前執行環境上下文,只要牢牢抓住這一點就能找到this的根源,this.functionthis.property就能準確定位實際物件。

2.this繫結規則

window 繫結

function sayAge () {
    console.log(this.age);
}
var  user = {
    name: 'ccy',
    age: 18
}
sayAge()複製程式碼

輸出結果為undefined,仔細思考當前函式執行的上下文,其實等價於window.sayAge()

this預設繫結在window全域性物件上

隱式繫結

function foo() { 
    console.log( this.a );
}
var obj = { 
    a: 2,
    foo: foo
};
obj.foo();複製程式碼

這段程式碼this繫結到了obj物件,當函式引用有上下文物件context時,隱式繫結規則會把this繫結到這個上下文物件

再看看隱式丟失問題

var bar=obj.foo;
bar();複製程式碼

輸出undefined,因為此時執行上下文為全域性物件,沒有a屬性

顯式繫結

在分析隱式繫結時,必須將函式作為物件的屬性,從而將此物件繫結在函式的執行上下文,但想想是不是很麻煩,顯示繫結可解決此問題。

function foo() { 
  console.log( this.a );
}
var obj = { 
  a:2
};
foo.call( obj );複製程式碼

用函式原型屬性 callapplybind都可以實現

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}複製程式碼

當然這些函式原型屬性都可以重寫以實現自己的需求,callapply的區別僅僅在於第二個引數開始apply傳遞陣列,call是將引數一個個傳遞,callbind的區別在於bind不能立即執行。

new 繫結

其實每當用 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的繫結物件。

參考資料

www.cnblogs.com/buzhiqiandu…


相關文章