公升入理解this 精華版

2021-10-01 12:03:51 字數 3563 閱讀 7589

在前幾篇博文中,關於this理解問題,我都有提到。 自認為理解很到位了,結果專案中,經常被this搞蒙頭。簡單的可能還好,如果函式呼叫位置不太明確的,只能大概加估計了。再次複習,加深理解。

js的作用域是基於函式的作用域的,在談到this指向問題時,很多情況下都是結合函式來說的。this到底是什麼,是個什麼東西。單獨的this就是js的乙個關鍵字,無任何函式,函式呼叫時,他便指向乙個物件。在理解問題之前,我們先得理解呼叫位置,函式呼叫棧。然後在介紹結合四法則,結合理解this

呼叫棧一種資料結構,可以理解為函式執行時呼叫的所有函式

呼叫位置函式在**中被呼叫的地方,包含函式呼叫的東西,或者說上下文。為什麼需要介紹這個,this就是在函式呼叫時繫結的,需要找到呼叫位置,才能方便分析出this的指向。

先來看看這段**

function baz () 

function bar ()

function foo ()

baz() ----> baz呼叫位置

我這裡依照之前的debug結果,注發布結果,就不再細分析。直觀的,我們不便分析出呼叫位置,我們可以結合瀏覽器或者編輯器debug工具,除錯檢視函式呼叫棧。

我們知道this是在函式呼叫時繫結的(前面已經提過),上面已經理解了呼叫位置。那麼在函式呼叫時,this是如何繫結的。這裡需要重點結合4個法則分析。

函式呼叫不帶任何修飾時,預設繫結到window頂層物件

這個很簡單,就是普通函式呼叫,this一般都是繫結到global.

實列**

function foo () 

var a = "oop ,blobal!!!";

var obj =

//帶修飾的foo呼叫, 帶物件引用的,函式呼叫

obj.foo() ===> obj

//不帶修飾的呼叫

foo() ----> global

函式呼叫處,是否包含上下文物件。如果函式位置出,擁有上下文物件。那麼this則指向它。這裡我叫他帶修飾的函式呼叫。如果函式呼叫位置處帶修飾,比如含有物件的引用。此時函式中的this則指向這個物件.

上面實列有說明,結合字面意思的實列很容易理解。重點說說隱式繫結丟失。這個是我這次複習this的主要原因。這個概念主要包括兩個小內容。

賦值時丟失

隱式賦值丟失

解釋:第一中很常見,就是將物件的方法賦值到物件外面的變數。導致this繫結的物件丟失。應用預設繫結

.......

var a = obj.foo

a() // this---> window

第二種發生在函式當作引數傳遞的時候, 函式當作引數傳遞,其實也是乙個隱式賦值

比如下面這樣,傳入值得時候,方法內部this得繫結就會丟失去,使用預設繫結 。當然這取決函式是否執行在嚴格模式下。只有在非嚴格模式下,才會使用預設邦定。

//定時器傳入隱式繫結函式

settimout(obj.foo) //這裡的foo是obj物件的乙個方法,此處省略具體宣告

實列

var obj = 

foo.call(obj)

這種方法,用來解決隱式繫結丟失問題。但是目前還沒發,需要稍作修改。即使顯示繫結變種,

實列

var obj = 

// 隱式繫結丟失

var dofoo = obj.foo //this---> window

//硬繫結

var dofoo = function ()

dofoo() ----> this--obj

硬繫結: 總的來說是解決了隱式繫結丟失問題,但同時也帶來了問題,this固定,不能在修改。

硬繫結使用改進 , bind. 負責接受值,返回

function foo (something) 

function bind (fn, obj)

}var obj = {}

var dofoo = bind(foo, obj)

var a= dofoo(3)

es5內建bind

上面的使用方式可以修改一下

var dofoo = foo.bind(obj) 這裡只需要傳入需要繫結this的物件即可。

通常在js opp的時候,會用到。經常會聽到程式設計師調侃,沒得物件new乙個就完事兒了。說的就是著玩兒。 在js中通過new關鍵字 構造函式呼叫,會生成新物件, 這期間構造內的this會指向 新物件

new 構造函式呼叫發生的事情:

1.建立新物件

2.新物件會鏈結__proto__

3.新物件會繫結到函式呼叫的this

4.如果函式呼叫沒有返回物件,那麼new 表示式呼叫會自動返回新物件。

在前面說的四法則中,在實際的場景中優先順序。

這裡重點說說 硬繫結和 new 構造呼叫優先順序順序

硬繫結通過包裝函式,包裝內層的顯示繫結函式呼叫, 繫結this。這裡使用es5的內建bind。他會返回乙個含有顯示繫結的硬繫結函式。這個外層函式會忽略this的繫結。

new構造他會修改硬繫結的this指向。以此看來 new優先順序高於硬繫結

實列

var obj = {}

function foo(something)

var dofoo = foo.bind(obj)

dofoo (3) //通過硬繫結對obj設定屬性

obj.a = 3

//通過new 改變內層this指向

var bar = new dofoo(2)

//可以看到 obj.a == 3 依舊未變

但是bar.a = 2 說明了new 改變了內部this指向

應用: 分布應用或者柯里化, new 結合bind使用。

function foo (a, b) 

或者var dofoo = foo.bind(null, 2);

dofoo(3)

使用null作為忽略this。避免不必要this的繫結. 雖然方便,但也存在問題,他會應用預設繫結。導致一系列問題.

安全this

未必免上述情況, 這裡介紹一種。更安全忽略this方法

//建立乙個空物件,用於this的繫結

var empty = object.create(null) //這樣建立的物件不存在原型關聯

//同樣是上述面列子,我們可以這樣呼叫foo

或者var dofoo = foo.bind(empty, 2)

dofoo(3)

這樣應用預設規則

Mac IDEA快捷鍵精華版

1.command n 快速建立方法,例如getter,setter,override等 2.option command t 包圍 使用if.else,try.catch,for,synchronized等包圍選中的 3.自動結束 行末自動新增分號 4.j,mid.button click 快速檢...

自動化測試基礎(精華版)

最近事情比較忙,好久沒更新部落格了。今天抽空來一篇自動化基礎的。首先來看一下什麼是自動化測試,我們前面說過什麼是軟體測試,來回顧一下概念,軟體測試 通過手工或自動化手段來檢測軟體中的錯誤和缺陷的過程。那麼自動化測試呢?就是通過自動化手段來檢測軟體中的錯誤和缺陷的過程了,ok,這樣說面試時是ok的,有...

Oracle 時間 問題總結精華版

1.oracle中如何獲取系統當前時間 oracle中如何獲取系統當前時間 select to char sysdate,yyyy mm dd hh24 mi ss from dual oracle裡獲取乙個時間的年 季 月 周 日的函式 select to char sysdate,yyyy fr...