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