成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

JavaScript || this

ShowerSun / 2744人閱讀

摘要:是中的一個(gè)屬性解析函數(shù)調(diào)用位置函數(shù)在程序代碼中被調(diào)用的位置,清楚調(diào)用位置才能明確的指向確定函數(shù)的調(diào)用位置最關(guān)鍵是分析調(diào)用棧為達(dá)到當(dāng)前指向位置所調(diào)用的所有函數(shù)。

關(guān)于this

this是JavaScript的一個(gè)關(guān)鍵字,自動(dòng)定義在所有函數(shù)中,難點(diǎn)在于this的指向。

this的指向在函數(shù)調(diào)用時(shí)進(jìn)行綁定,它的context取決于函數(shù)調(diào)用時(shí)的各種條件,與函數(shù)定義位置無(wú)關(guān)

1 this的作用

this可以使不同的context對(duì)象重復(fù)使用已經(jīng)存在、聲明的函數(shù),無(wú)需針對(duì)每個(gè)對(duì)象編寫(xiě)不同版本的函數(shù)

function identify() {
    return this.name.toUpperCase();
}
function speak() {
    var greeting = "Hello, i"m " + identify.call( this );    
    console.log( greeting );
}

var me = {name: "Kyle"};
var you = {name: "Reader"};

identify.call( me );         // KYLE
identify.call( you );       // READER

speak.call( me );              // "Hello, i"m KYLE"
speak.call( you );              // "Hello, i"m READER"
2 誤解

this并不是指向函數(shù)本身

在任何情況下,this都不指向函數(shù)的詞法作用域

3 this是什么?

this是在函數(shù)被調(diào)用時(shí)發(fā)生綁定,其指向取決于函數(shù)調(diào)用的位置。

當(dāng)一個(gè)函數(shù)被調(diào)用是,會(huì)創(chuàng)建一個(gè)執(zhí)行上下文(context)。其中包含函數(shù)的調(diào)用位置(調(diào)用棧)、函數(shù)的調(diào)用方式和傳入的參數(shù)等信息。thiscontext中的一個(gè)屬性

4 this解析 4.1 函數(shù)調(diào)用位置

函數(shù)在程序代碼中被調(diào)用的位置,清楚調(diào)用位置才能明確this的指向

確定函數(shù)的調(diào)用位置:最關(guān)鍵是分析調(diào)用棧(為達(dá)到當(dāng)前指向位置所調(diào)用的所有函數(shù))。分析調(diào)用棧,可以得出真正的調(diào)用位置

function baz() {
    // 當(dāng)前調(diào)用棧是:baz
    // 所以當(dāng)前調(diào)用位置時(shí)全局作用域

    console.log("baz");
    bar(); // <-- bar的調(diào)用位置
}

function bar() {
    // 當(dāng)前調(diào)用棧是:baz --> bar
    // bar的調(diào)用位置在baz中

    console.log("bar");
    foo(); // <-- bar的調(diào)用位置
}

function foo() {
    // 當(dāng)前調(diào)用棧是:baz --> bar --> foo
    // foo的調(diào)用位置在bar中

    console.log("foo");
}
baz();   //  --> baz的調(diào)用位置
4.2 this的綁定規(guī)則

在分析清楚調(diào)用位置后,根據(jù)this綁定的四條規(guī)則決定綁定對(duì)象。四條規(guī)則分別對(duì)應(yīng)四種不同的函數(shù)調(diào)用方式

總共有四條綁定規(guī)則,其優(yōu)先級(jí)是:默認(rèn)綁定 < 隱式綁定 < 顯式綁定 < new綁定

默認(rèn)綁定:作為獨(dú)立調(diào)用的函數(shù)

隱式綁定:作為對(duì)象的方法調(diào)用的函數(shù)

顯式綁定(硬綁定):使用call()、apply()bind()方法,強(qiáng)制將對(duì)象綁定到函數(shù)的this

new綁定:

4.2.1 默認(rèn)綁定

默認(rèn)綁定指將函數(shù)作為獨(dú)立的函數(shù)來(lái)調(diào)用,默認(rèn)綁定將this綁定到全局對(duì)象

分析隱式綁定時(shí),一個(gè)對(duì)象內(nèi)部包含一個(gè)指向函數(shù)的屬性,并且通過(guò)對(duì)象的屬性間接引用函數(shù),將this間接綁定到該對(duì)象上

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

a在全局作用域中聲明,是全局對(duì)象的一個(gè)屬性;

foo()使用不帶任何修飾的函數(shù)進(jìn)行調(diào)用,只能使用默認(rèn)綁定規(guī)則;此時(shí),非嚴(yán)格模式下this指向全局對(duì)象,所有this.a被解析為全局變量a

在嚴(yán)格模式中,this不能綁定到全局對(duì)象,this只能綁定到undefined

function foo() {
    "use strict";
    console.log(this.a);
}
var a = 2;
foo();  // TypeError: this is undefined

4.2.2 隱式綁定

判斷函數(shù)的調(diào)用位置是否有上下文對(duì)象,隱式綁定將this綁定到調(diào)用方法的上下文對(duì)象上。

function foo() {
    console.log(this.a);
}
var obj = {
    a: 2,
    foo: foo
};
obj.foo();  // 2   foo()的調(diào)用位置包含上下文對(duì)象obj,this隱式綁定到obj對(duì)象

對(duì)象屬性引用鏈中,只有最后一層會(huì)影響調(diào)用位置

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

var obj2 = {
    a: 42,
    foo: foo

obj.obj2.foo();  // 42   實(shí)際是通過(guò)obj對(duì)象的obj2屬性對(duì)象來(lái)調(diào)用foo()函數(shù),this指向obj2

隱式丟失

被隱式綁定的函數(shù)會(huì)丟失綁定對(duì)象,然后應(yīng)用默認(rèn)綁定,非嚴(yán)格模式下將this綁定到全局對(duì)象。

隱式綁定丟失發(fā)生在將隱式綁定的函數(shù)賦值給另外的變量,通過(guò)改變了來(lái)調(diào)用函數(shù)

function foo() {
    console.log(this.a);
}
var obj = {
    a: 2,
    foo: foo
};
var bar = obj.foo;   //  函數(shù)別名,傳遞引用
var  a = "global a";
bar();  // "global a",函數(shù)的調(diào)用位置,bar()其實(shí)是一個(gè)不帶任何修飾的函數(shù)調(diào)用,所以應(yīng)用默認(rèn)的綁定規(guī)則

在函數(shù)中將回調(diào)函數(shù)作為參數(shù)傳入時(shí),參數(shù)傳遞是一種隱式賦值(傳遞引用),所以應(yīng)用默認(rèn)綁定規(guī)則

function foo() {
    console.log(this.a);
}
function doFoo(fn) {
    // fn是obj.foo函數(shù)本身的一個(gè)引用

    fn();   // fn的調(diào)用位置
}
var obj = {
    a: 2,
    foo: foo
};
var bar = obj.foo;   //  函數(shù)別名,傳遞引用
var  a = "global a";
doFoo(obj.foo);  // "global a",傳入的函數(shù)被隱式賦值,應(yīng)用默認(rèn)綁定規(guī)則

setTimeout(obj.foo, 100);   //"global a",使用語(yǔ)言本身的內(nèi)置函數(shù)時(shí)道理相同

4.2.3 顯式綁定

在JavaScript中,函數(shù)是對(duì)象,每個(gè)函數(shù)對(duì)象都定義有call()、apply()bind()方法,bind()在ES5中。

call()apply()方法:

第一個(gè)方法是一個(gè)對(duì)象,將該對(duì)象綁定到this

可以直接指定綁定的對(duì)象,稱為顯示綁定

call()、apply()區(qū)別在于其他參數(shù)

function foo() {
    console.log(this.a);
}
var obj = {
    a: 2,
    foo: foo
};
foo.call(obj);   // 2  通過(guò)foo.call(obj);,在調(diào)用foo()時(shí)強(qiáng)制將其this綁定到obj對(duì)象

顯式綁定仍然會(huì)有綁定丟失問(wèn)題:可以使用顯示綁定的一個(gè)變形來(lái)解決這個(gè)問(wèn)題;

硬綁定

創(chuàng)建一個(gè)函數(shù)bar(),在內(nèi)部調(diào)用foo.call(obj),強(qiáng)制將foothis綁定到obj對(duì)象上,無(wú)論怎樣調(diào)用bar()函數(shù),都會(huì)手動(dòng)在obj對(duì)象上調(diào)用foo,因此foothis指向不會(huì)改變

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

bar();   //  2
setTimeout( bar, 100 ); // 2
// 硬綁定的bar不能再修改它的this指向
bar.call(window);   // 2

硬綁定的應(yīng)用場(chǎng)景

創(chuàng)建一個(gè)包裹函數(shù),傳入所有的參數(shù),并返回接收到的所有值

function foo(sth) {
    return this.a + sth;
}
var obj = {
    a: 2
};
var bar = function() {
    // 將arguments傳入需要調(diào)用的函數(shù)
    return foo.apply(obj, arguments);   
}

bar(3);   //  2 + 3 = 5

創(chuàng)建一個(gè)可以重復(fù)使用的函數(shù)

function foo(sth) {
    return this.a + sth;
}
var obj = {
    a: 2
};
// 簡(jiǎn)單的輔助綁定函數(shù)
function bind(fn, obj) {
    return function() {
        return fn.apply(obj, arguments);
    }
}

var bar = bind(foo, obj);
bar(3);   //  2 + 3 = 5

硬綁定是一種非常常見(jiàn)的模式,ES5提供內(nèi)置Function.prototype.bind方法:返回一個(gè)硬綁定的新函數(shù),bind(obj)將參數(shù)obj設(shè)置為this的上下文,并調(diào)用原始函數(shù)。

function foo(sth) {
    return this.a + sth;
}
var obj = {
    a: 2
};

var bar = foo.bind(obj);
bar(3);   //  2 + 3 = 5

4.2.4 new綁定

JavaScript中的new機(jī)制與傳統(tǒng)面向?qū)ο笳Z(yǔ)言不同。JavaScript中構(gòu)造函數(shù)只是使用new操作符調(diào)用的函數(shù),使用new操作符調(diào)用函數(shù)時(shí):

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

新對(duì)象被執(zhí)行__proto__鏈接

新創(chuàng)建的對(duì)象被綁定到函數(shù)調(diào)用時(shí)的this

如果函數(shù)沒(méi)有返回其他對(duì)象,new表達(dá)式中的函數(shù)調(diào)用自動(dòng)返回新創(chuàng)建的對(duì)象

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

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

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

判斷this的指向:找到函數(shù)的調(diào)用位置,并根據(jù)優(yōu)先級(jí)判斷應(yīng)用的規(guī)則,默認(rèn)綁定的優(yōu)先級(jí)最低

顯示綁定的優(yōu)先級(jí)高于隱式綁定:在判斷時(shí)優(yōu)先考慮顯示綁定

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

var obj1 = {
    a: 2;
    foo: foo
};
var objb = {
    a: 4;
    foo: foo
};

obj1.foo();  // 2
obj2.foo();  // 4

obj1.foo.call(obj2);   // 4
obj2.foo.call(obj1);   // 2

new綁定的優(yōu)先級(jí)高于隱式綁定:

new綁定的優(yōu)先級(jí)的高于顯示綁定:

bar被硬綁定到obj1對(duì)象上,但是new bar(3)并未將obj1.a修改為4;

new bar(3)修改了調(diào)用bar()中的this,得到一個(gè)新對(duì)象

function foo(a) {
    this.a = a;
}
obj1 = {};
var bar = foo.bind(obj1);
bar(2);
console.log(obj1.a);   // 2

var baz = new bar(4);
console.log(obj1.a);  // 2
console.log(baz.a);  // 4

4.4 根據(jù)優(yōu)先級(jí)判斷函數(shù)調(diào)用位置應(yīng)用的規(guī)則

函數(shù)是否在new中調(diào)用?如果是,this綁定新創(chuàng)建的對(duì)象

函數(shù)是否通過(guò)call()、apply()顯示綁定?或者bind()硬綁定?如果是,this指向綁定的對(duì)象。

函數(shù)是否在某個(gè)上下文對(duì)象中調(diào)用?如果是,this指向那個(gè)上下文對(duì)象

如果不是上述三種情況,使用默認(rèn)綁定。嚴(yán)格模式下綁定到undefined,非嚴(yán)格模式下綁定到全局對(duì)象

4.5 綁定例外 4.5.1 被忽略的this

nullundefined作為this的綁定對(duì)象傳入call()、apply()bind()方法,在調(diào)用時(shí)被忽略,實(shí)際應(yīng)用默認(rèn)綁定規(guī)則。

使用null來(lái)忽略this綁定可能產(chǎn)生副作用:安全的做法是傳入一個(gè)特殊對(duì)象,將this綁定到這個(gè)對(duì)象不會(huì)產(chǎn)生任何副作用。Object.create(null)。

5 this詞法

ES6中的箭頭函數(shù)不能使用上述4種規(guī)則,而是根據(jù)外層(函數(shù)或全局)作用域來(lái)絕對(duì)this。箭頭函數(shù)常用于回調(diào)函數(shù)中。

function foo() {
    // 返回一個(gè)箭頭函數(shù)
    return (a) => {
        // this繼承自foo()
        console.log(this.a);
    }
}
var obj = {
    a: 2
};

var obj2 = {
    a: 42
};

var bar = foo.call(obj1);  
bar.call(obj2);   // 2, 不是42

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

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

相關(guān)文章

  • JavaScript深入淺出

    摘要:理解的函數(shù)基礎(chǔ)要搞好深入淺出原型使用原型模型,雖然這經(jīng)常被當(dāng)作缺點(diǎn)提及,但是只要善于運(yùn)用,其實(shí)基于原型的繼承模型比傳統(tǒng)的類繼承還要強(qiáng)大。中文指南基本操作指南二繼續(xù)熟悉的幾對(duì)方法,包括,,。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。 怎樣使用 this 因?yàn)楸救藢儆趥吻岸?,因此文中只看懂?8 成左右,希望能夠給大家?guī)?lái)幫助....(據(jù)說(shuō)是阿里的前端妹子寫(xiě)的) this 的值到底...

    blair 評(píng)論0 收藏0
  • javascript技術(shù)難點(diǎn)(三)之this、new、apply和call詳解

    摘要:第四點(diǎn)也要著重講下,記住構(gòu)造函數(shù)被操作,要讓正常作用最好不能在構(gòu)造函數(shù)里 4) this、new、call和apply的相關(guān)問(wèn)題 講解this指針的原理是個(gè)很復(fù)雜的問(wèn)題,如果我們從javascript里this的實(shí)現(xiàn)機(jī)制來(lái)說(shuō)明this,很多朋友可能會(huì)越來(lái)越糊涂,因此本篇打算換一個(gè)思路從應(yīng)用的角度來(lái)講解this指針,從這個(gè)角度理解this指針更加有現(xiàn)實(shí)意義。 下面我們看看在ja...

    ghnor 評(píng)論0 收藏0
  • JavaScript進(jìn)階之’this

    摘要:所以相同點(diǎn)是,在全局范圍內(nèi),全局變量終究是屬于老大的。只生效一次引入了。只生效一次在箭頭函數(shù)中,與封閉詞法環(huán)境的保持一致。我通常把這些原始函數(shù)叫做構(gòu)造函數(shù)。在里面你可以嵌套函數(shù),也就是你可以在函數(shù)里面定義函數(shù)。 showImg(https://img-blog.csdnimg.cn/20190522000008399.jpg?x-oss-process=image/watermark,...

    shenhualong 評(píng)論0 收藏0
  • Javascript 深入淺出This

    摘要:中函數(shù)的調(diào)用有以下幾種方式作為對(duì)象方法調(diào)用,作為函數(shù)調(diào)用,作為構(gòu)造函數(shù)調(diào)用,和使用或調(diào)用。作為構(gòu)造函數(shù)調(diào)用中的構(gòu)造函數(shù)也很特殊,構(gòu)造函數(shù),其實(shí)就是通過(guò)這個(gè)函數(shù)生成一個(gè)新對(duì)象,這時(shí)候的就會(huì)指向這個(gè)新對(duì)象如果不使用調(diào)用,則和普通函數(shù)一樣。 this 是 JavaScript 比較特殊的關(guān)鍵字,本文將深入淺出的分析其在不同情況下的含義,可以這樣說(shuō),正確掌握了 JavaScript 中的 th...

    Y3G 評(píng)論0 收藏0
  • 學(xué)習(xí)React之前你需要知道的的JavaScript基礎(chǔ)知識(shí)

    摘要:和類在開(kāi)始時(shí)遇到類組件,只是需要有關(guān)類的基礎(chǔ)。畢竟,中的條件呈現(xiàn)僅再次顯示大多數(shù)是而不是特定的任何內(nèi)容。 在我的研討會(huì)期間,更多的材料是關(guān)于JavaScript而不是React。其中大部分歸結(jié)為JavaScript ES6以及功能和語(yǔ)法,但也包括三元運(yùn)算符,語(yǔ)言中的簡(jiǎn)寫(xiě)版本,此對(duì)象,JavaScript內(nèi)置函數(shù)(map,reduce,filter)或更常識(shí)性的概念,如:可組合性,可重用...

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

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

0條評(píng)論

閱讀需要支付1元查看
<