摘要:硬綁定硬綁定后無論怎么調(diào)用,都不會影響函數(shù)的綁定硬綁定的典型應用是如下的包裹函數(shù)將對象硬編碼進去即將內(nèi)部函數(shù)用硬綁定到某個對象,無論怎么調(diào)用這個包裹函數(shù),都不會影響內(nèi)部函數(shù)的。
this
ES6中的箭頭函數(shù)采用的是詞法作用域。
為什么要使用this:使API設計得更簡潔且易于復用。
this即不指向自身,也不指向函數(shù)的詞法作用域。
this的指向只取決于函數(shù)的調(diào)用方式
this綁定規(guī)則new > 顯示綁定 > 隱式綁定 > 默認綁定
默認綁定當獨立函數(shù)調(diào)用時,不管是否在調(diào)用棧中,this都指向全局對象(瀏覽器中為window)
嚴格模式下,不能將全局對象用于默認綁定。
var a = 2; function foo(){ console.log(this.a); } function bar(){ var a = 5; foo(); } bar(); // 2隱式綁定
當函數(shù)引用有上下文對象時,隱式綁定規(guī)則會把函數(shù)調(diào)用中的this綁定到這個上下文對象。
對象屬性引用鏈中只有最后一層在調(diào)用位置中起作用。
要求:對象內(nèi)部必須包含一個指向函數(shù)的屬性,該對象可通過這個屬性間接引用函數(shù)。
function foo() { console.log( this.a ); } var obj2 = { a: 42, foo: foo }; var obj1 = { a: 2, obj2: obj2 }; obj1.obj2.foo(); // 42
隱式丟失
function foo() { console.log( this.a ); } var obj = { a: 2, foo: foo }; var bar = obj.foo; // 這里bar將引用foo函數(shù)本身,所以不帶有函數(shù)對象的上下文 var a = "oops, global"; // a是全局對象的屬性 bar(); // "oops, global"
和回調(diào)函數(shù)的情況下(參數(shù)傳遞時的隱式賦值)
function foo() { console.log( this.a ); } function doFoo(fn) { // 參數(shù)傳遞時,相當于fn = obj.foo,就和上個例子一樣了 fn(); // <-- call-site! } var obj = { a: 2, foo: foo }; var a = "oops, global"; // `a` also property on global object doFoo( obj.foo ); // "oops, global"顯式綁定
采用call()和apply(),通過傳入一個對象(若為基本類型,會被封裝函數(shù)轉(zhuǎn)為對象—裝箱),將this綁定到該對象。
硬綁定
function foo() { console.log( this.a ); } var obj = { a: 2 }; var bar = function() { foo.call( obj ); }; bar(); // 2 setTimeout( bar, 100 ); // 2 // 硬綁定后bar無論怎么調(diào)用,都不會影響foo函數(shù)的this綁定 bar.call( window ); // 2
硬綁定的典型應用是如下的包裹函數(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 ); // 將obj對象硬編碼進去 }; var b = bar( 3 ); // 2 3 console.log( b ); // 5
即將內(nèi)部函數(shù)用apply硬綁定到某個對象,無論怎么調(diào)用這個包裹函數(shù),都不會影響內(nèi)部函數(shù)的this。
bind輔助函數(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 ); // 利用參數(shù)將obj傳入進去 }; } var obj = { a: 2 }; var bar = bind( foo, obj ); // bind( foo, obj )會返回一個包裹函數(shù) var b = bar( 3 ); // 2 3 console.log( b ); // 5
總結(jié):上述包裹函數(shù),想要包裹其他函數(shù),只能一個一個重復寫,硬編碼的方式導致不能被重用,當某種功能需要多次重復使用時,將其抽象出來,成為函數(shù)。
new綁定任何函數(shù)都可能被用作構(gòu)造函數(shù),當函數(shù)被new操作符“構(gòu)造調(diào)用”時,會執(zhí)行下面操作:
1. 創(chuàng)建一個新對象(若該函數(shù)不是JS內(nèi)置的,則創(chuàng)建一個新的Object對象);
2. 將this綁定到這個對象;
3. 執(zhí)行構(gòu)造函數(shù)中的代碼(為這個新對象添加屬性);
4. 若函數(shù)沒有返回其他對象,則自動返回這個新對象;若函數(shù)有return返回的是非對象,則還是自動返回這個新對象,即覆蓋那個非對象。
function foo(a) { this.a = a; } var bar = new foo( 2 ); console.log( bar.a ); // 2補充說明
間接引用
function foo() { console.log( this.a ); } var a = 2; var o = { a: 3, foo: foo }; var p = { a: 4 }; o.foo(); // 3 (p.foo = o.foo)(); // 2,由于p.foo = o.foo的返回值是目標函數(shù)的引用,所以調(diào)用位置是foo(),而不是p.foo()或o.foo()
箭頭函數(shù):不使用這四個this規(guī)則,根據(jù)詞法作用域來決定this。
function foo() { // 返回一個箭頭函數(shù) return (a) => { // `this` here is lexically adopted from `foo()` console.log( this.a ); }; } var obj1 = { a: 2 }; var obj2 = { a: 3 }; // foo()不是箭頭函數(shù),他的this被綁定到obj1 var bar = foo.call( obj1 ); // foo.call( obj1 )返回箭頭函數(shù),所以bar為箭頭函數(shù) bar.call( obj2 ); // 2! 箭頭函數(shù)的this無法被修改,new也不行
如下為和箭頭函數(shù)一樣的模式:
function foo() { var self = this; // lexical capture of `this` setTimeout( function(){ console.log( self.a ); }, 100 ); } var obj = { a: 2 }; foo.call( obj ); // 2this綁定的趣題:
知乎鏈接-arguments對象調(diào)用
更多博客:https://github.com/Lmagic16/blog
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/98364.html
摘要:的四種綁定規(guī)則的種綁定規(guī)則分別是默認綁定隱式綁定顯示綁定綁定。綁定中的操作符,和其他語言中如的機制是不一樣的。規(guī)則例外在顯示綁定中,對于和的綁定將不會生效。它也是作為機制的一種替換,解決之前綁定過程各種規(guī)則帶來的復雜性。 徹底搞懂 JS 中 this 機制 摘要:本文屬于原創(chuàng),歡迎轉(zhuǎn)載,轉(zhuǎn)載請保留出處:https://github.com/jasonGeng88/blog 目錄 t...
摘要:實際上并不存在什么構(gòu)造函數(shù),只存在對于函數(shù)的構(gòu)造調(diào)用發(fā)生構(gòu)造函數(shù)的調(diào)用時,會自動執(zhí)行下邊的操作創(chuàng)建一個全新的對象。說明綁定的優(yōu)先級高于硬綁定。 原文閱讀 ??js中的this是很容易讓人覺得困惑的地方,這篇文章打算說一下this綁定的幾種情況,相信可以解決大部分關于this的疑惑。 this是在運行的時候綁定的,不是在編寫的時候綁定的,函數(shù)調(diào)用的方式不同,就可能使this所綁定的對象不...
摘要:在嚴格模式下調(diào)用函數(shù)則不影響默認綁定。回調(diào)函數(shù)丟失綁定是非常常見的。因為直接指定的綁定對象,稱之為顯示綁定。調(diào)用時強制把的綁定到上顯示綁定無法解決丟失綁定問題。 (關注福利,關注本公眾號回復[資料]領取優(yōu)質(zhì)前端視頻,包括Vue、React、Node源碼和實戰(zhàn)、面試指導) 本周正式開始前端進階的第三期,本周的主題是this全面解析,今天是第9天。 本計劃一共28期,每期重點攻克一個面試重...
摘要:關于的指向問題算的上是中的一個十分重要的問題了。首先,的指向問題可以用一句話總結(jié)就是總是指向調(diào)用的對象,也就是說指向誰與函數(shù)聲明的位置沒有關系,只與調(diào)用的位置有關。此外注意幾種特殊情況,特別是中的箭頭函數(shù)。 關于this的指向問題算的上是js中的一個十分重要的問題了。今天把這個問題總結(jié)下,加深下自己對this的理解。首先,this的指向問題可以用一句話總結(jié)就是:this總是指向調(diào)用的對...
摘要:運行規(guī)則根據(jù)的運作原理,我們可以看到,的值和調(diào)用棧通過哪些函數(shù)的調(diào)用運行到調(diào)用當前函數(shù)的過程以及如何被調(diào)用有關。 1. this的誕生 假設我們有一個speak函數(shù),通過this的運行機制,當使用不同的方法調(diào)用它時,我們可以靈活的輸出不同的name。 var me = {name: me}; function speak() { console.log(this.name); }...
閱讀 2651·2019-08-30 15:53
閱讀 2876·2019-08-29 16:20
閱讀 1084·2019-08-29 15:10
閱讀 1023·2019-08-26 10:58
閱讀 2195·2019-08-26 10:49
閱讀 633·2019-08-26 10:21
閱讀 705·2019-08-23 18:30
閱讀 1638·2019-08-23 15:58