摘要:但是如果某個函數確實使用了,那默認綁定規則會把綁定到全局對象在瀏覽器中這個對象是,這將導致不可預計的后果比如修改全局對象。實際上并不存在所謂的構造函數,只有對于函數的構造調用。使用來調用函數,或者說發生構造函數調用時,會自動執行下面的操作。
1. 默認綁定this 實際上是在函數被調用時發生的綁定,它指向什么完全取決于函數在哪里被調用(也就是函數的調用方法)。
獨立函數調用時,應用 this 的默認綁定, this 指向全局對象
如果使用嚴格模式(strict mode),那么全局對象將無法使用默認綁定,因此 this 會綁定到 undefined
觀察下面這段代碼
function aba () { console.log(this) } function bab () { "use strict" console.log(this) } var obj = { aba: aba, bab: bab } aba() //Window {frames: Window, postMessage: ?, blur: ?, focus: ?, close: ?,?…} bab() //undefined obj.aba() //{aba: ?, bab: ?} obj.bab() //{aba: ?, bab: ?}2. 隱式綁定
在一個對象內部包含一個指向函數的屬性,并通過這個屬性間接引用函數,從而把 this 間接(隱式)綁定到這個對象上。
當函數引用有上下文對象時,隱式綁定規則會把函數調用中的 this 綁定到這個上下文對象。
所以上個示例代碼中, 調用 obj.aba()時 this 被綁定到 obj,因此 this.aba 和 obj.aba 是一樣的。
對象屬性引用鏈中只有
最頂層或者說最后一層會影響調用位置。
function foo() { console.log( this.a ); } var obj2 = { a: 42, foo: foo }; var obj1 = { a: 2, obj2: obj2 }; obj1.obj2.foo(); // 42
一個最常見的 this 綁定問題就是被隱式綁定的函數會丟失綁定對象,也就是說它會應用默認綁定,從而把 this 綁定到全局對象或者 undefined 上,取決于是否是嚴格模式。
function fun1 () { console.log(this) } var obj = { fun1: fun1, fun2: function () { console.log(this) } } var getfun1 = obj.fun1 var getfun2 = obj.fun2 function doCallBack (cb) { //參數傳遞其實就是一種隱式賦值,因此我們傳入函數時也會被隱式賦值 cb() } function testSetTimeout (fun) { setTimeout(fun, 0) } fun1() // Window {frames: Window, postMessage: ?, blur: ?, focus: ?, close: ?,?…} obj.fun1() // {fun1: ?, fun2: ?} obj.fun2() // {fun1: ?, fun2: ?} getfun1() // Window {frames: Window, postMessage: ?, blur: ?, focus: ?, close: ?,?…} getfun2() // Window {frames: Window, postMessage: ?, blur: ?, focus: ?, close: ?,?…} doCallBack(obj.fun1) // Window {frames: Window, postMessage: ?, blur: ?, focus: ?, close: ?,?…} doCallBack(obj.fun2) // Window {frames: Window, postMessage: ?, blur: ?, focus: ?, close: ?,?…} testSetTimeout(obj.fun1) // Window {frames: Window, postMessage: ?, blur: ?, focus: ?, close: ?,?…} testSetTimeout(obj.fun2) // Window {frames: Window, postMessage: ?, blur: ?, focus: ?, close: ?,?…}3. 顯式綁定
使用 call 、 apply 、 bind 或者箭頭函數顯示綁定函數調用的 this
如果把 null 或者 undefined 作為 this 的綁定對象傳入 call、apply 或者 bind,這些值在調用時會被忽略,實際應用的是默認綁定規則
var obj = { c: 33, fun: function (a,b) { console.log( "a:" + a + ", b:" + b + ", c:" + this.c ) } } // 把數組“展開”成參數 obj.fun.apply( null, [2, 3] ); a:2, b:3, c:undefined // 使用 bind(..) 進行柯里化 var bar = obj.fun.bind( null, 2 ); bar( 3 ); // a:2, b:3, c:undefined
上面代碼中 apply 、 bind 這兩種方法都需要傳入一個參數當作 this 的綁定對象。如果函數并不關心 this 的話,仍然需要傳入一個占位值,這時 null 可能是一個不錯的選擇。
但是如果某個函數確實使用了 this,那默認綁定規則會把 this 綁定到全局對象(在瀏覽器中這個對象是 window),這將導致不可預計的后果(比如修改全局對象)。
在 JavaScript 中,構造函數只是一些被 new 操作符調用的普通函數而已。
實際上并不存在所謂的“構造函數”,只有對于函數的“構造調用”。使用 new 來調用函數,或者說發生構造函數調用時,會自動執行下面的操作。
1 創建(或者說構造)一個全新的對象。
2 這個新對象會被執行 [[ 原型 ]] 連接。
3 這個新對象會綁定到函數調用的 this。
4 如果函數沒有返回其他對象,那么 new 表達式中的函數調用會自動返回這個新對象。
注意: 對 bind 返回的函數進行構造調用時,實際調用的是原函數,調用 bind 時傳入的第一個參數將被忽略,剩余參數作為構造調用的參數傳入原函數
function test (a, b) { this.a = a this.b = b this.say = function () { console.log(`a: ${this.a}, b: ${this.b}, c: ${this.c}`) } } var bindObj = { c: 12 } var bindReturn = test.bind(bindObj, 1, 2) var newBindReturn = new bindReturn() newBindReturn.say() // a: 1, b: 2, c: undefined console.log(bindObj) // {c: 12} bindReturn() console.log(bindObj) // {c: 12, a: 1, b: 2, say: ?}
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/90087.html
摘要:注此讀書筆記只記錄本人原先不太理解的內容經過閱讀你不知道的后的理解。作用域及閉包基礎,代碼運行的幕后工作者引擎及編譯器。 注:此讀書筆記只記錄本人原先不太理解的內容經過閱讀《你不知道的JS》后的理解。 作用域及閉包基礎,JS代碼運行的幕后工作者:引擎及編譯器。引擎負責JS程序的編譯及執行,編譯器負責詞法分析和代碼生成。那么作用域就像一個容器,引擎及編譯器都從這里提取東西。 ...
摘要:有種內置類型,分別是除對象之外,其他統稱為基本類型。另一個需要注意的是數組確切地說,數組也是的一個子類型我們可以通過下面的方法檢查變量是不是數組處理未聲明的變量時,會返回這是因為有一個特殊的安全防范機制。 js有7種內置類型,分別是undefined null boolean string number symbol object除對象之 Object 外,其他統稱為基本類型。符號 ...
摘要:本書屬于基礎類書籍,會有比較多的基礎知識,所以這里僅記錄平常不怎么容易注意到的知識點,不會全記,供大家和自己翻閱不錯,下冊的知識點就這么少,非常不推介看下冊上中下三本的讀書筆記你不知道的上讀書筆記你不知道的中讀書筆記你不知道的下讀書筆記第三 本書屬于基礎類書籍,會有比較多的基礎知識,所以這里僅記錄平常不怎么容易注意到的知識點,不會全記,供大家和自己翻閱; 不錯,下冊的知識點就這么少,非...
摘要:閉包在循環中的應用延遲函數的回調會在循環結束時才執行事實上,當定時器運行時即使沒給迭代中執行的是多有的回調函數依然是在循環結束后才會被執行,因此會每次輸出一個出來。 閉包在循環中的應用 延遲函數的回調會在循環結束時才執行;事實上,當定時器運行時即使沒給迭代中執行的是 setTime(..., 0),多有的回調函數依然是在循環結束后才會被執行,因此會每次輸出一個6出來。 for(var...
摘要:的分句會創建一個塊作用域,其聲明的變量僅在中有效。而閉包的神奇作用是阻止此事發生。依然持有對該作用域的引用,而這個引用就叫做閉包。當然,無論使用何種方式對函數類型的值進行傳遞,當函數在別處被調用時都可以觀察到閉包。 date: 16.12.8 Thursday 第一章 作用域是什么 LHS:賦值操作的目標是誰? 比如: a = 2; RHS:誰是賦值操作的源頭? 比如: conso...
閱讀 1346·2021-11-25 09:43
閱讀 1904·2021-11-12 10:36
閱讀 6018·2021-09-22 15:05
閱讀 3488·2019-08-30 15:55
閱讀 2017·2019-08-26 14:06
閱讀 3648·2019-08-26 12:17
閱讀 507·2019-08-23 17:55
閱讀 2459·2019-08-23 16:23