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

資訊專欄INFORMATION COLUMN

【YDKJS讀書筆記】關(guān)于Js中的this Part1

siberiawolf / 1349人閱讀

摘要:貼一句書中的原文就是說在代碼中很簡單,沒有任何修飾的調(diào)用,就可以理解為全局的作用域?qū)ο蟆_@種鏈?zhǔn)劫x值,指向問題在中叫做。在這種傳一個(gè)參數(shù)作為對(duì)象的功能方面,與是等價(jià)的。看了以上文章對(duì)于解決面試題應(yīng)該會(huì)有不小的幫助。

書讀到"this & object prototype"這一卷。 章節(jié)到了“this All Makes Sense Now!”

書里面開篇就提到,this并不復(fù)雜,只不過被很多程序員加了自己的臆想以訛傳訛,說到底,還是基礎(chǔ)知識(shí)不熟悉。
的確,看過很多技術(shù)文章,分析this都有那種管中窺豹的感覺就是著重在舉例,論述這個(gè)現(xiàn)象,而不求甚解。
閑言少敘,開始總結(jié)。

首先說一個(gè)重要的技術(shù)名詞,call-site,我們平時(shí)在debug的時(shí)候,可能會(huì)接觸到callstack這個(gè)詞,感覺上其實(shí)有那么一點(diǎn)類似。

我理解:
call-stack:是一連串的方法執(zhí)行的鏈?zhǔn)浇Y(jié)果
call-site:只是上一個(gè)調(diào)用當(dāng)前方法上下文環(huán)境,可以理解為context。

比如下面這個(gè)片段:

function callfirst(){
    // call-stack:callfirst
    // call-site:全局
    callsecond();
}
function callsecond(){
    // call-stack:callfirst -> callsecond
    // call-site:callfirst
}
callfirst();

為什么說到這個(gè)call-site,確定this對(duì)象其實(shí)就是找到call-site的過程。

說到這里,還要再提一個(gè)細(xì)節(jié),js中的this,不是面向?qū)ο笾袀鹘y(tǒng)的概念,這個(gè)this不是放在function中就是這個(gè)function的context,也不是任何場合都代表了整個(gè)js運(yùn)行環(huán)境中的context,這個(gè)this,你就可以理解為是剛才提到的call-site,必須是有依據(jù)的context。

下面就總結(jié)一下找到call-site的方法,也就是如何正確找到并使用this。(規(guī)則我就直接使用原文的副標(biāo)題)

1.Default Binding:看看如下代碼片段
function foo() {
    console.log( this.a );
}

var a = 2;

foo();

這里出現(xiàn)this的地方,是foo方法里,我們先確定call-site,顯而易見,foo方法的call-site就是最后一行foo,隸屬于全局對(duì)象,那么這個(gè)this就呼之欲出了,這個(gè)this就代表這個(gè)代碼的作用域,而this.a訪問的也就是var a = 2;這條語句賦值的屬性,所以控制臺(tái)會(huì)打印出一個(gè)2。
貼一句書中的原文:

called with a plain, un-decorated function reference.

就是說在代碼中很簡單,沒有任何修飾的調(diào)用,this就可以理解為全局的作用域?qū)ο蟆?br>但是這種規(guī)則,不適用于strict mode環(huán)境下的js代碼,如果用在strict mode中,以上代碼需要改寫成為

function foo() {
    console.log( this.a );
}

var a = 2;

(function(){
    "use strict";

    foo(); // 2
})();
2.Implicit Binding:還是看代碼
function foo() {
    console.log( this.a );
}

var obj = {
    a: 2,
    foo: foo
};

obj.foo();

這種直譯為隱式綁定的方法,確定call-site的方法就是看是由誰調(diào)用的方法,在上面這個(gè)例子中,再直白以及明顯不過了,obj中有一個(gè)foo屬性,綁定的foo方法,那么此時(shí)foo方法中的call-site就是obj,obj中有一個(gè)屬性是a,所以代碼會(huì)輸出2

變形:

function foo() {
    console.log( this.a );
}

var obj2 = {
    a: 42,
    foo: foo
};

var obj1 = {
    a: 2,
    obj2: obj2
};

obj1.obj2.foo(); // 42

如果遇到這種鏈?zhǔn)降娘L(fēng)格,就本著就近原則,離foo方法最近的obj2就是foo的call-site,方法中this.a的值就是obj2中a的值。

在Implicit Binding的情況下會(huì)有一種叫Implicitly Lost的情況發(fā)生,簡單直白點(diǎn)說就是剛才那種鏈?zhǔn)秸{(diào)用的方式,被隱藏在了各種其他的情況之下,舉例來說明。

function foo() {
    console.log( this.a );
}

var obj = {
    a: 2,
    foo: foo
};

var bar = obj.foo;

var a = "oops, global";

bar();

上面這種情況將obj.foo賦值給了bar, 按照慣性思維,看到obj.foo第一反應(yīng),我覺得this應(yīng)該等價(jià)于obj,然而事實(shí)卻哐哐打臉,
上面代碼的foo的call-site是bar,雖然鏈?zhǔn)綇?fù)制了一大堆給了bar,但實(shí)際上,bar在這個(gè)時(shí)點(diǎn)是等價(jià)于foo的,所以這個(gè)方法的call-site就是bar,那么this.a的值就是全局屬性的a,與obj就不相干了。
與上面情況相同的還有如下幾種變種情況:

function foo() {
    console.log( this.a );
}

function doFoo(fn) {
    fn();
}

var obj = {
    a: 2,
    foo: foo
};

var a = "oops, global"; 

doFoo( obj.foo ); 

刨除一切感官上的理解,最終調(diào)起foo方法的是fn()這句話,fn的值雖然是由obj.foo傳過來的,但其實(shí)這種情況與上面說到的方式完全是等價(jià)的
解析一下,fn()就是foo的call-site,而根據(jù)第一個(gè)default binding原則,fn前面是干凈沒有任何修飾符的,所以foo中的this代表的就是全局對(duì)象。

這里需要強(qiáng)調(diào)的就是,鏈?zhǔn)椒椒o論是賦值還是作為方法的參數(shù),不能被長長的語句迷惑雙眼,照準(zhǔn)call-site是理順?biāo)悸返囊磺蟹ㄩT。

這種鏈?zhǔn)劫x值,this指向問題在js中叫做fall back to default binding。

3.Explicit Binding

說到這個(gè)顯示綁定,就得提到兩個(gè)方法,一個(gè)叫做call,另一個(gè)叫apply,在現(xiàn)在這個(gè)時(shí)點(diǎn),我們暫且理解幾個(gè)點(diǎn),這兩個(gè)方法,是所有function對(duì)象都可以調(diào)用的內(nèi)建方法(涉及到prototype),他們的第一個(gè)參數(shù),我們就可以理解為this對(duì)象,這是一種強(qiáng)制把this注入到方法中的一種手段。舉個(gè)例子

function foo() {
    console.log( this.a );
}

var obj = {
    a: 2
};

foo.call( obj );

還是熟悉的味道,但是我們卻換了配方,我們不直接調(diào)用foo方法,而是使用foo中的call方法,把obj傳到call中作為foo中的this對(duì)象,控制臺(tái)會(huì)為我們輸出一個(gè)2,call可以換成apply。

foo.apply(obj);

在這種傳一個(gè)參數(shù)作為this對(duì)象的功能方面,call與apply是等價(jià)的。

4 new Binding

這個(gè)恐怕也是很多使用js的朋友們最容易混淆的地方,new在js中生成的只是一個(gè)function,new過是在一個(gè)function前面搶了一個(gè)new單詞,而這樣表示會(huì)讓function有一些新的變化
大體上有4點(diǎn):

產(chǎn)生一個(gè)新的function對(duì)象

這個(gè)與原型鏈有關(guān),暫且不說

new出來的function對(duì)象調(diào)用的方法是使用的this,就是它本身

除對(duì)象本身改變自己本身以外,每次new出來的對(duì)象都是全新的對(duì)象(這話我再潤色一下)

上例子:

function foo(a) {
    this.a = a;
}

var bar = new foo( 2 );
console.log( bar.a );

這個(gè)比之之前的復(fù)雜情況就太淺顯了,望文生義即可。

看了以上文章對(duì)于解決this面試題應(yīng)該會(huì)有不小的幫助。

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

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

相關(guān)文章

  • JavaScript設(shè)計(jì)模式之發(fā)布-訂閱模式(觀察者模式)-Part1

    摘要:設(shè)計(jì)模式與開發(fā)實(shí)踐讀書筆記。發(fā)布訂閱模式又叫觀察者模式,它定義了對(duì)象之間的一種一對(duì)多的依賴關(guān)系。附設(shè)計(jì)模式之發(fā)布訂閱模式觀察者模式數(shù)據(jù)結(jié)構(gòu)和算法系列棧隊(duì)列優(yōu)先隊(duì)列循環(huán)隊(duì)列設(shè)計(jì)模式系列設(shè)計(jì)模式之策略模式 《JavaScript設(shè)計(jì)模式與開發(fā)實(shí)踐》讀書筆記。 發(fā)布-訂閱模式又叫觀察者模式,它定義了對(duì)象之間的一種一對(duì)多的依賴關(guān)系。當(dāng)一個(gè)對(duì)象的狀態(tài)發(fā)生改變時(shí),所有依賴它的對(duì)象都將得到通知。 例...

    muzhuyu 評(píng)論0 收藏0
  • JS

    摘要:棧學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)與算法讀書筆記。棧又名堆棧,是一種遵循后進(jìn)先出原則的有序集合。新添加或待刪除的元素都保存在棧的末尾,稱作棧頂,另一端稱作棧底。在棧里,新元素都靠近棧頂,舊元素都接近棧底。 棧 《學(xué)習(xí)JavaScript數(shù)據(jù)結(jié)構(gòu)與算法》讀書筆記。 棧(stack)又名堆棧,是一種遵循后進(jìn)先出(LIFO)原則的有序集合。新添加或待刪除的元素都保存在棧的末尾,稱作棧頂,另一端稱作棧底。在棧里,...

    Lin_R 評(píng)論0 收藏0
  • JavaScript設(shè)計(jì)模式之發(fā)布-訂閱模式(觀察者模式)-Part2

    摘要:設(shè)計(jì)模式與開發(fā)實(shí)踐讀書筆記。看此文章前,建議先看設(shè)計(jì)模式之發(fā)布訂閱模式觀察者模式在中,已經(jīng)介紹了什么是發(fā)布訂閱模式,同時(shí),也實(shí)現(xiàn)了發(fā)布訂閱模式。 《JavaScript設(shè)計(jì)模式與開發(fā)實(shí)踐》讀書筆記。 看此文章前,建議先看JavaScript設(shè)計(jì)模式之發(fā)布-訂閱模式(觀察者模式)-Part1 在Part1中,已經(jīng)介紹了什么是發(fā)布-訂閱模式,同時(shí),也實(shí)現(xiàn)了發(fā)布-訂閱模式。但是,就Part1...

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

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

0條評(píng)論

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