国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

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

tianren124 / 2212人閱讀

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

1. this的誕生

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

var me = {name: "me"};

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

speak.call(me) //me

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

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

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í), 函數(shù)會(huì)創(chuàng)建一個(gè)activation object(執(zhí)行上下文), 這個(gè)對(duì)象包括了函數(shù)在哪里被調(diào)用(調(diào)用棧),函數(shù)的調(diào)用方式,傳入的參數(shù),以及this值。

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

2.2 運(yùn)行規(guī)則

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

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

當(dāng)函數(shù)是被獨(dú)立調(diào)用時(shí),this值在非嚴(yán)格模式下為全局對(duì)象, 嚴(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í),函數(shù)的調(diào)用棧為bar -> foo,調(diào)用方式是獨(dú)立調(diào)用,且是在非嚴(yán)格模式下,此時(shí)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

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

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

但是我們?cè)倏纯聪旅孢@種情況。要注意的是,bar的值是對(duì)函數(shù)foo的引用,因此此時(shí)foo的調(diào)用并沒有上下文對(duì)象的引用,因此應(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值為全局對(duì)象(非嚴(yán)格模式),要么通過對(duì)象方法調(diào)用,this指向調(diào)用的對(duì)象。
那我想不通過對(duì)象調(diào)用,而是獨(dú)立調(diào)用時(shí)又能指定this值為某個(gè)對(duì)象呢?這時(shí),call,apply就誕生了。它的第一個(gè)參數(shù)是this值,幫助我們明確指定函數(shù)調(diào)用時(shí)this的值。

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

foo.call(obj); //2

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

在ES5中提供了Function.prototype.bind,它的應(yīng)用場(chǎng)景就是幫助你predicable的綁定this值。常用的應(yīng)用場(chǎ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í),如果第一個(gè)參數(shù)是null, undefined,則應(yīng)用默認(rèn)綁定規(guī)則。為避免傳入null, undefined時(shí)錯(cuò)誤的改變了全局值,最好創(chuàng)建一個(gè)空對(duì)象代替null, undefined

var ? = Object.create(null);

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

明白new的運(yùn)作原理:

創(chuàng)建一個(gè)新對(duì)象;

對(duì)象鏈接到[[prototype]]上;

this綁定到這個(gè)新對(duì)象上;

有顯式的return,返回return,否則返回這個(gè)新對(duì)象。

2.2.5 優(yōu)先級(jí)

new > 顯示綁定(call,apply,bind) > 隱式綁定(方法調(diào)用) > 默認(rèn)綁定(獨(dú)立函數(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ī)則。因?yàn)檫@里的this不是使用的傳統(tǒng)this機(jī)制,而是使用的詞法作用域,根據(jù)外層的作用域來決定this。應(yīng)用機(jī)制不一樣,該this也不能通過顯示綁定來修改。

5. 總結(jié)

下一次再看到this的時(shí)候,我們問自己兩個(gè)問題:

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

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

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

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

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

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

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

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/81958.html

相關(guān)文章

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

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

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

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

    codeKK 評(píng)論0 收藏0
  • You don't know cross-origin

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

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

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

    mingzhong 評(píng)論0 收藏0
  • You Don't Know Js 閱讀筆記

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

    wanglu1209 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<