成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

《You Don't Know JS》閱讀理解——this

tianren124 / 2215人閱讀

摘要:運行規(guī)則根據(jù)的運作原理,我們可以看到,的值和調(diào)用棧通過哪些函數(shù)的調(diào)用運行到調(diào)用當(dāng)前函數(shù)的過程以及如何被調(diào)用有關(guān)。

1. this的誕生

假設(shè)我們有一個speak函數(shù),通過this的運行機制,當(dāng)使用不同的方法調(diào)用它時,我們可以靈活的輸出不同的name。

var me = {name: "me"};

function speak() {
  console.log(this.name);
}

speak.call(me) //me

但是如果沒有this, 這時我們需要顯示的傳遞上下文給該函數(shù)。這時必須硬性的指定上下文,代碼的復(fù)雜度增加,靈活性也欠缺。

function speak(context) {
  console.log(context.name);
}
2. this的運行機制 2.1 運行原理

When a function is invoked, an activation record, otherwise known as an execution context, is created. This record contains information about where the function was called from (the call-stack), how the function was invoked, what parameters were passed, etc. One of the properties of this record is the this reference which will be used for the duration of that function"s execution.

當(dāng)函數(shù)被調(diào)用時, 函數(shù)會創(chuàng)建一個activation object(執(zhí)行上下文), 這個對象包括了函數(shù)在哪里被調(diào)用(調(diào)用棧),函數(shù)的調(diào)用方式,傳入的參數(shù),以及this值。

因此,我們可以看到,this值是在函數(shù)調(diào)用時賦值的,而不是在聲明的時候。是動態(tài)的。

2.2 運行規(guī)則

根據(jù)this的運作原理,我們可以看到,this的值和調(diào)用棧(通過哪些函數(shù)的調(diào)用運行到調(diào)用當(dāng)前函數(shù)的過程)以及如何被調(diào)用有關(guān)。

2.2.1 Default Binding(默認(rèn)綁定)

當(dāng)函數(shù)是被獨立調(diào)用時,this值在非嚴(yán)格模式下為全局對象, 嚴(yán)格模式下為undefined.

var a = 1;
function foo() {
  var a = 2;
  console.log(this.a);
}

function bar() {
  debuuger;
  foo();
}

bar();

打開chrome devtool可以看到,在調(diào)用foo時,函數(shù)的調(diào)用棧為bar -> foo,調(diào)用方式是獨立調(diào)用,且是在非嚴(yán)格模式下,此時this值指向window,輸出1。

2.2.2 Implicit Binding(隱式綁定)
var = 1;
function foo() {
  debugger;
  console.log(this.a);
}
var obj = {
  a: 2,
  foo: foo
}

obj.foo(); //2

此時,調(diào)用foo時,函數(shù)前加上了對obj這個對象的引用,輸出obj.a。

因此,如果有上下文對象引用了函數(shù),隱式綁定規(guī)則會指定this值為該引用對象。

但是我們再看看下面這種情況。要注意的是,bar的值是對函數(shù)foo的引用,因此此時foo的調(diào)用并沒有上下文對象的引用,因此應(yīng)用的是default binding, 輸出1。要注意這種賦值的情況。

var a = 1;
function foo() {
  debugger;
  console.log(this.a);
}
var obj = {
  a: 2,
  foo: foo
}

var bar = obj.foo;

bar(); //1
2.2.3 Explicit Binding(顯式綁定)

上面兩種情況,要么this值為全局對象(非嚴(yán)格模式),要么通過對象方法調(diào)用,this指向調(diào)用的對象。
那我想不通過對象調(diào)用,而是獨立調(diào)用時又能指定this值為某個對象呢?這時,call,apply就誕生了。它的第一個參數(shù)是this值,幫助我們明確指定函數(shù)調(diào)用時this的值。

var a = 1;
function foo() {
  debugger;
  console.log(this.a);
}
var obj = {
  a: 2
}

foo.call(obj); //2

通過call, apply,我們可以在調(diào)用時明確指定this值。還有一種情況是,有時候我們希望this值綁定在我們給定的對象上,而函數(shù)只需要接受一些參數(shù)。特別是在第三方庫中,它會提供一種方法,接收方法需要的參數(shù),但是不希望你意外的修改了方法的this值,這時它可能會采用bind這種硬性綁定的方法明確的指出this值。

在ES5中提供了Function.prototype.bind,它的應(yīng)用場景就是幫助你predicable的綁定this值。常用的應(yīng)用場景為包裹函數(shù)、事件綁定函數(shù)、setTimeout中綁定this

//包裹函數(shù),用來接受參數(shù)
function multiple(num) {
  console.log(this.pen, num);
  return this.pen * num;
}

var priceMapping = {
  pen: 10
}

function calTotalPrices() {
  return multiple.apply(priceMapping, arguments);
}

var total = calTotalPrices(3);
console.log(total); //30
//事件綁定
var states = {
  clickCount: 0
}
function clickHandler() {
  this.clickCount++;
  console.log(this.clickCount);
}
button.addEventListener("click", clickHandler.bind(states));

注意:當(dāng)使用顯示綁定時,如果第一個參數(shù)是null, undefined,則應(yīng)用默認(rèn)綁定規(guī)則。為避免傳入null, undefined時錯誤的改變了全局值,最好創(chuàng)建一個空對象代替null, undefined。

var ? = Object.create(null);

foo.call(?);
2.2.4 new Binding(new綁定)

明白new的運作原理:

創(chuàng)建一個新對象;

對象鏈接到[[prototype]]上;

this綁定到這個新對象上;

有顯式的return,返回return,否則返回這個新對象。

2.2.5 優(yōu)先級

new > 顯示綁定(call,apply,bind) > 隱式綁定(方法調(diào)用) > 默認(rèn)綁定(獨立函數(shù)調(diào)用)

function foo(sth) {
  this.b = sth;
  console.log("a:", this.a, "b:", this.b);
}

var a = "window";
var obj1 = {
  a: "obj1",
  foo: foo,
}

var obj2 = {
  a: "obj2",
  foo: foo,
}

obj1.foo("obj1"); //a: obj1 b: obj1
obj1.foo.call(obj2, "obj2"); //a: obj2 b: obj2; 顯示 > 隱式
var bar = foo.bind(obj1);
new bar("new"); //new > 顯示
4. 箭頭函數(shù)

箭頭函數(shù)中的this并不適用于以上四種規(guī)則。因為這里的this不是使用的傳統(tǒng)this機制,而是使用的詞法作用域,根據(jù)外層的作用域來決定this。應(yīng)用機制不一樣,該this也不能通過顯示綁定來修改。

5. 總結(jié)

下一次再看到this的時候,我們問自己兩個問題:

where to call: 函數(shù)的調(diào)用位置是?

how to call: 函數(shù)的調(diào)用方法是?應(yīng)用的規(guī)則是?

應(yīng)用規(guī)則4條(按優(yōu)先級排序):

new (新創(chuàng)建的對象)

顯式綁定 (綁定到指定對象,call, apply, bind:可預(yù)測的this);

隱式綁定 (調(diào)用的上下文對象,注意間接引用的錯誤);

默認(rèn)綁定 (全局對象或undefined注意函數(shù)體是否為嚴(yán)格模式);

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/81958.html

相關(guān)文章

  • 讀書筆記(you don't know js): this的理解(沒寫完...)

    摘要:基本概念首先,函數(shù)不能存儲的值,指向哪里,取決于調(diào)用它的對象。如果沒有這個對象,那默認(rèn)就是調(diào)用非嚴(yán)格模式下。也就是說是在運行的時候定義的,不是在綁定的時候定義的。 基本概念 首先,函數(shù)不能存儲this的值,this指向哪里,取決于調(diào)用它的對象。如果沒有這個對象,那默認(rèn)就是window調(diào)用(非嚴(yán)格模式下)。也就是說this是在運行的時候定義的,不是在綁定的時候定義的。 funct...

    freewolf 評論0 收藏0
  • You Don't Know JS閱讀理解——作用域

    摘要:在我們的程序中有很多變量標(biāo)識符,我們現(xiàn)在或者將來將使用它。當(dāng)我們使用時,如果并沒有找到這個變量,在非嚴(yán)格模式下,程序會默認(rèn)幫我們在全局創(chuàng)建一個變量。詞法作用域也就是說,變量的作用域就是他聲明的時候的作用域。 作用域 定義 首先我們來想想作用域是用來干什么的。在我們的程序中有很多變量(標(biāo)識符identifier),我們現(xiàn)在或者將來將使用它。那么多變量,我咋知道我有沒有聲明或者定義過他呢,...

    codeKK 評論0 收藏0
  • You don't know cross-origin

    摘要:為什么會存在跨域問題同源策略由于出于安全考慮,瀏覽器規(guī)定不能操作其他域下的頁面,不能接受其他域下的請求不只是,引用非同域下的字體文件,還有引用非同域下的圖片,也被同源策略所約束只要協(xié)議域名端口有一者不同,就被視為非同域。 showImg(https://segmentfault.com/img/remote/1460000017093859?w=1115&h=366); Why 為什么...

    hersion 評論0 收藏0
  • [翻譯]You Don't Know JS: this & Object Prot

    摘要:引用是從匿名函數(shù)內(nèi)部引用自身的唯一方法,不過,最好的方法是避免使用匿名函數(shù),至少在那些需要引用自身的時候,使用命名函數(shù)或者表達(dá)式。 [翻譯]Chapter1 this or that 第一次翻譯,翻譯的不好,已經(jīng)再盡全力s去翻譯了,如果哪里看不明點,請出門左轉(zhuǎn)下邊原文地址 英文原文點擊這里 javascript中最令人困惑的東西就是this關(guān)鍵字,它在每個函數(shù)作用域中都會自動定義的一個...

    mingzhong 評論0 收藏0
  • You Don't Know Js 閱讀筆記

    摘要:回調(diào)傳遞函數(shù)是將函數(shù)當(dāng)做值并作為參數(shù)傳遞給函數(shù)。這個例子中就是因為事件綁定機制中的傳入了回調(diào)函數(shù),產(chǎn)生了閉包,引用著所在的作用域,所以此處的數(shù)據(jù)無法從內(nèi)存中釋放。 javascript作用域 一門語言需要一套設(shè)計良好的規(guī)則來存儲變量,并且之后可以方便的找到這些變量,這逃規(guī)則被稱為作用域。 這也意味著當(dāng)我們訪問一個變量的時候,決定這個變量能否訪問到的依據(jù)就是這個作用域。 一、詞法作用域 ...

    wanglu1209 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<