摘要:但在嚴格模式下默認綁定不起作用顯式綁定顯式綁定用到了和方法,因為可以直接指定的綁定對象,因此稱之為顯式綁定。隱式綁定顯式綁定當我們使用顯式綁定時,輸出的值為的值所以顯式綁定的優(yōu)先級更高。
上篇文章介紹了this的隱式綁定(implicit binding),接著介紹this其他三種綁定方式
默認綁定 (Default Binding)
顯式綁定 (Explicit Binding)
new綁定(new Binding)
默認綁定 (Default Binding)這個是最簡單的綁定,最常用的調(diào)用類型:獨立函數(shù)調(diào)用
function foo() { console.log( this.a ); } var a = 2; foo(); // 2
首先foo()在全局作用域中被調(diào)用,根據(jù)調(diào)用域(call-site),此時this綁定到了全局,所以結(jié)果很明顯。
但在嚴格模式下,默認綁定不起作用
function foo() { "use strict"; console.log( this.a ); } var a = 2; foo(); // TypeError: `this` is `undefined`顯式綁定 (Explicit Binding)
顯式綁定用到了call()和apply()方法,因為可以直接指定this的綁定對象,因此稱之為顯式綁定。
function foo() { console.log( this.a ); } var obj = { a: 2 }; foo.call( obj ); // 2
通過foo.call(),我們可以在調(diào)用foo時強制把它this綁定到obj上。
硬綁定(Hard Binding)因為我們強制把foo的this綁定到了obj,無論之后如何調(diào)用bar,之后的操作并不會覆蓋之前的,它總會在obj上調(diào)用foo。
function foo() { console.log( this.a ); } var obj = { a: 2 }; var bar = function() { foo.call( obj ); }; bar(); // 2 setTimeout( bar, 100 ); // 2 // `bar` hard binds `foo`"s `this` to `obj` // so that it cannot be overriden bar.call( window ); // 2
硬綁定的應(yīng)用場景就是創(chuàng)建一個包裹函數(shù),負責接收參數(shù)并返回值:
function foo(something) { console.log( this.a, something ); return this.a + something; } var obj = { a: 2 }; var bar = function() { return foo.apply( obj, arguments ); }; var b = bar( 3 ); // 2 3 console.log( b ); // 5
另一種使用方法是創(chuàng)建一個可以重復使用的輔助函數(shù)
function foo(something) { console.log( this.a, something ); return this.a + something; } // simple `bind` helper function bind(fn, obj) { return function() { return fn.apply( obj, arguments ); }; } var obj = { a: 2 }; var bar = bind( foo, obj ); var b = bar( 3 ); // 2 3 console.log( b ); // 5
由于硬綁定是非常常用的,所以ES5提供了內(nèi)置方法Function.prototype.bind()
function foo(something) { console.log( this.a, something ); return this.a + something; } var obj = { a: 2 }; var bar = foo.bind( obj ); var b = bar( 3 ); // 2 3 console.log( b ); // 5new Binding
使用new來調(diào)用foo()時,我們會構(gòu)造一個新對象并把它綁定到foo()調(diào)用中的this上。
function foo(n) { this.studentNum = n; this.name = "cnio" } var bar = new foo(1) console.log(bar) // foo {studentNum: 1, name: "cnio"}
如果foo原型鏈上也有內(nèi)容,比如添加
foo.prototype.getName = function() { return this.name; }
在控制臺打印出的proto中,就有g(shù)etName屬性。
使用new關(guān)鍵字時,會發(fā)生如下幾個步驟
創(chuàng)建一個全新的對象。
這個新對象會被執(zhí)行[[Prototype]]連接。
這個新對象會綁定到函數(shù)調(diào)用的this。
如果函數(shù)沒有返回其他對象,那么new表達式中的函數(shù)調(diào)用會自動返回這個新對象。
優(yōu)先級比較前面已經(jīng)了解了this綁定的四條規(guī)則,但是這幾種某次應(yīng)用了多條該怎么辦?所以需要測試一下優(yōu)先級,也就是誰的權(quán)利更大些,就聽誰的,否則小弟this將不知所措了。
隱式綁定 VS 顯式綁定function foo() { console.log( this.a ); } var obj1 = { a: 2, foo: foo }; var obj2 = { a: 3, foo: foo }; obj1.foo(); // 2 obj2.foo(); // 3 obj1.foo.call( obj2 ); // 3 obj2.foo.call( obj1 ); // 2
當我們使用call(obj2)顯式綁定時,輸出的值為obj2的值(a=3),所以顯式綁定的優(yōu)先級更高。
new綁定 VS 隱式綁定function foo(something) { this.a = something; } var obj1 = { foo: foo }; var obj2 = {}; obj1.foo( 2 ); console.log( obj1.a ); // 2 obj1.foo.call( obj2, 3 ); console.log( obj2.a ); // 3 var bar = new obj1.foo( 4 ); console.log( obj1.a ); // 2 console.log( bar.a ); // 4
可以看到,new綁定的優(yōu)先級>隱式綁定
那么new綁定的優(yōu)先級與顯式綁定優(yōu)先級呢?因為new和apply/call無法一起使用,但硬綁定也是顯式綁定的一種,可以替換測試
function foo(something) { this.a = something; } var obj1 = {}; var bar = foo.bind( obj1 ); bar( 2 ); console.log( obj1.a ); // 2 var baz = new bar( 3 ); console.log( obj1.a ); // 2 console.log( baz.a ); // 3
new修改了硬綁定調(diào)用bar()中的this,代碼感覺無法修改this綁定,但是又的確修改了this綁定,這個很特殊,理論上我們可以認為new綁定優(yōu)先級>顯式綁定
綜上,優(yōu)先級比較如下
new綁定 > 顯式綁定 > 隱式綁定
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/78766.html
摘要:應(yīng)該算是前期比較容易混淆的一個關(guān)鍵字了,在這里,我就打算按照我的理解來說一下首先呢,的值是跟運行時被調(diào)用的位置相關(guān)的,而不是詞法作用域。來一個例子在瀏覽器中執(zhí)行,會發(fā)現(xiàn),如果作為一個函數(shù)單獨調(diào)用,那么指向的就是全局對象。 this應(yīng)該算是前期比較容易混淆的一個關(guān)鍵字了,在這里,我就打算按照我的理解來說一下 首先呢,this的值是跟運行時被調(diào)用的位置相關(guān)的,而不是詞法作用域。 也就是說,...
摘要:真正的理解閉包的原理與使用更加透徹綁定的四種規(guī)則機制你不知道的人稱小黃書,第一次看到這本書名就想到了一句話你懂得,翻閱后感覺到很驚艷,分析的很透徹,學習起來也很快,塊級作用域語句語句相當于比較麻煩而且用在對象上創(chuàng)建的塊作用域僅僅在聲明中有效 真正的理解閉包的原理與使用 更加透徹this綁定的四種規(guī)則機制 你不知道的JavaScript 人稱小黃書,第一次看到這本書名 就想到了一句話...
摘要:和作用域判別失敗相關(guān),而代表作用域判別成功,但是對結(jié)果的操作是非法的不合理的。在中,構(gòu)造函數(shù)只是使用操作符時被調(diào)用的函數(shù),它們并不屬于一個類,也不會實例化一個類。也就是說,中,不存在所謂的構(gòu)造函數(shù),只有對函數(shù)的構(gòu)造調(diào)用。 與其他語言相比,js中的this有所不同,也是比較頭疼的問題。在參考了一些資料后,今天,就來深入解析一下this指向問題,有不對的地方望大家指出。 為什么要用this...
摘要:最近剛剛看完了你不知道的上卷,對有了更進一步的了解。你不知道的上卷由兩部分組成,第一部分是作用域和閉包,第二部分是和對象原型。附錄詞法這一章并沒有說明機制,只是介紹了中的箭頭函數(shù)引入的行為詞法。第章混合對象類類理論類的機制類的繼承混入。 最近剛剛看完了《你不知道的 JavaScript》上卷,對 JavaScript 有了更進一步的了解。 《你不知道的 JavaScript》上卷由兩部...
摘要:那默認綁定到哪呢,一般是上,嚴格模式下是。這種情況下,函數(shù)里的默認綁定為上下文對象,等價于打印故輸出。只接受兩個參數(shù),且第二個參數(shù)必須是數(shù)組,這個數(shù)組代表原函數(shù)的參數(shù)列表。即繼承原函數(shù)的原型將這個新對象綁定到此函數(shù)的上。 js 的 this 綁定問題,讓多數(shù)新手懵逼,部分老手覺得惡心,這是因為this的綁定 ‘難以捉摸’,出錯的時候還往往不知道為什么,相當反邏輯。讓我們考慮下面代碼: ...
閱讀 1686·2021-11-19 09:40
閱讀 2939·2021-09-24 10:27
閱讀 3228·2021-09-02 15:15
閱讀 1888·2019-08-30 15:54
閱讀 1213·2019-08-30 15:54
閱讀 1378·2019-08-30 13:12
閱讀 642·2019-08-28 18:05
閱讀 2809·2019-08-27 10:53