亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

Javascript的this理解

王笑朝 / 1265人閱讀

摘要:一默認(rèn)綁定默認(rèn)綁定默認(rèn)綁定是指在非嚴(yán)格模式下,且沒有使用別的綁定規(guī)則時(shí),根據(jù)函數(shù)調(diào)用調(diào)用棧的上下文來綁定對象全局對象。把函數(shù)傳入語言內(nèi)置函數(shù)。使用時(shí)盡量避免混用,否則會(huì)造成難以維護(hù)的后果。

在理解javascript的this之前,首先先了解一下作用域。

作用域分為兩種:

1、詞法作用域:引擎在當(dāng)前作用域或者嵌套的子作用域查找具有名稱標(biāo)識(shí)符的變量。(引擎如何查找和在哪查找。定義過程發(fā)生在代碼書寫階段)
2、動(dòng)態(tài)作用域:在運(yùn)行時(shí)被動(dòng)態(tài)確定的作用域。

詞法作用域和動(dòng)態(tài)作用域的區(qū)別是:詞法作用域是在寫代碼或定義時(shí)確定的;動(dòng)態(tài)作用域是在運(yùn)行時(shí)確定的。

this的綁定規(guī)則

this是在調(diào)用時(shí)被綁定,取決于函數(shù)的調(diào)用位置。由此可以知道,一般情況下(非嚴(yán)格模式下),this都會(huì)根據(jù)函數(shù)調(diào)用(調(diào)用棧)的上下文來綁定對象。

一、默認(rèn)綁定

默認(rèn)綁定:默認(rèn)綁定是指在非嚴(yán)格模式下,且沒有使用別的綁定規(guī)則時(shí),this根據(jù)函數(shù)調(diào)用(調(diào)用棧)的上下文來綁定對象(全局對象)。(嚴(yán)格模式下則綁定undefined)

舉個(gè)栗子:

function foo() {
    console.log(this.a);
};
function bar() {
    var a = 3;
    foo();
}
var a = 2;
bar();  //調(diào)用棧在全局作用域,this綁定全局對象

運(yùn)行結(jié)果為: 2
//加上"use strict"運(yùn)行結(jié)果則會(huì)變成this is undefined

這里的函數(shù)調(diào)用時(shí),使用了默認(rèn)綁定,函數(shù)調(diào)用(調(diào)用棧)的上下文是全局作用域,因此this綁定了全局對象(global)。

eg2:
function foo() {
    console.log(this.a)
};
var a = 2;
(function() {
    "use strict"
    foo();
})();

運(yùn)行結(jié)果為: 2

這里需要注意:對于默認(rèn)綁定,決定this綁定對象的不是調(diào)用位置是否處于嚴(yán)格模式,而是函數(shù)體是否處于嚴(yán)格模式(函數(shù)體處于嚴(yán)格模式則this綁定undefined;否則this綁定全局對象)。另外:嚴(yán)格模式和非嚴(yán)格模式雖然有可能可以綁定,但是最好不混用。

間接引用一般也是會(huì)應(yīng)用默認(rèn)綁定規(guī)則。

eg:
function foo() {
    console.log(this.a);
};
var a = 2;
var o = { a: 3, foo: foo };
var p = { a: 4 };
o.foo();   //3
(p.foo = o.foo)();  //2

賦值表達(dá)式 p.foo = o.foo的返回值是直接引用目標(biāo)函數(shù)foo。

二、隱式綁定

隱式綁定:由上下文對象調(diào)用,綁定到上下文對象。

舉個(gè)栗子:

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

這段代碼中,foo()被當(dāng)做引用屬性添加到obj對象中,obj調(diào)用這個(gè)引用屬性函數(shù)時(shí),會(huì)使用該引用屬性上下文,this會(huì)被綁定到obj對象。(這個(gè)函數(shù)嚴(yán)格來說不屬于obj對象,只是作為引用屬性)。屬于隱式綁定。

而下面foo()函數(shù)的直接執(zhí)行,并不是obj對象引用,所以上下文對象是全局對象。故this綁定了undefined。屬于默認(rèn)綁定。

對象引用鏈中只有上一層或者說最后一層在調(diào)用位置中起作用。

注意:

隱式綁定的函數(shù)會(huì)丟失綁定對象。此時(shí)它會(huì)應(yīng)用默認(rèn)綁定,將this綁定到全局對象或者undefined上,取決于是否是嚴(yán)格模式。
eg:

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

運(yùn)行結(jié)果:"biubiubiu"

解析:看似bar是obj.foo的一個(gè)引用,實(shí)際上bar是直接引用了函數(shù)foo,是一個(gè)單純的函數(shù)調(diào)用,故實(shí)為默認(rèn)綁定。

參數(shù)傳遞就是隱式賦值,因此傳入函數(shù)時(shí)也會(huì)被隱式賦值。
eg:

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

運(yùn)行結(jié)果: "biubiubiu"

解析:實(shí)際上參數(shù)也是隱式賦值,但是參數(shù)傳入函數(shù)中,并在函數(shù)中執(zhí)行。此時(shí)也是直接引用了函數(shù)foo,因此也是單純的函數(shù)調(diào)用,采用了默認(rèn)綁定。

把函數(shù)傳入語言內(nèi)置函數(shù)。(與上面情況基本相似,將自己聲明函數(shù)改成語言內(nèi)置函數(shù))回調(diào)函數(shù)丟失this的情況比較常見,況且還有調(diào)用回調(diào)函數(shù)的函數(shù)可能還會(huì)修改this。

三、顯式綁定

顯式綁定:直接將this綁定到指定對象上。Javascript中絕大多數(shù)函數(shù)和自己所創(chuàng)建的函數(shù)都可以使用這兩種顯式綁定的方法。

1、.call()
2、.apply()
這兩種綁定方法,第一個(gè)參數(shù)是this綁定的對象。(如果傳入的參數(shù)是原始值(字符串類型、布爾類型、數(shù)字類型),這個(gè)原始值就會(huì)被轉(zhuǎn)成對象形式(new String、new Boolean、new Number)這個(gè)稱為:裝箱)

舉個(gè)栗子:

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

運(yùn)行結(jié)果: 2

然鵝,顯示綁定并不能解決綁定丟失的問題。這個(gè)時(shí)候來了一位新朋友 -- 硬綁定(bind)。

3、.bind() (硬綁定是常見場景,故es5提供了該內(nèi)置方法 Function.prototype.bind。)
bind()會(huì)返回一個(gè)新編碼函數(shù),把this綁定在指定參數(shù)上,并調(diào)用函數(shù)。

舉個(gè)栗子:

function foo(e) {
    console.log(this.a + e);
    return this.a + e;
};
var obj = {
    a: 2
}
var bar = foo.bind(obj); //新編碼函數(shù)
var b = bar(3); // 2 3
console.log(b); // 5

bind()還有一個(gè)功能將除了第一個(gè)用于綁定this的參數(shù)之外的其他參數(shù)傳給下層的函數(shù)部分應(yīng)用,是“柯里化”的一種)。

這里涉及到一個(gè)概念:把null或者undefined作為this的綁定對象傳入call、apply、bind,這些值在調(diào)用的時(shí)候會(huì)被忽略,實(shí)際應(yīng)用默認(rèn)綁定規(guī)則。
應(yīng)用場景:
1、使用apply()展開一個(gè)數(shù)組,并作為參數(shù)傳遞給一個(gè)函數(shù)。
2、bind()對參數(shù)進(jìn)行柯里化(預(yù)先設(shè)置一些參數(shù))。

舉個(gè)栗子:

function foo(a,b) {
    console.log("a:" + a + ",b:" + b);
};
//數(shù)組“展開”成參數(shù)
foo.apply(null,[2,3]);  //a:2,b:3
//bind()柯里化
var bar = foo.bind(null,2);
bar(3);  //a:2,b:3

解析:傳入一個(gè)參數(shù)作為this綁定對象,如果不傳則使用占位符(null),此時(shí)會(huì)使用默認(rèn)綁定規(guī)則。

上面這個(gè)例子可能會(huì)產(chǎn)生一定的副作用,如果需要運(yùn)用這種場景并且更加安全??梢詣?chuàng)建一個(gè)空對象(可以用任意喜歡的名字來命名)。

var ? = Object.create(null);
//上面這個(gè)例子就可以改寫為:
foo.apply(?,[2,3]); //a:2,b:3
var bar = foo.bind(?,2);
bar(3);  //a:2,b:3

注意:硬綁定之后不能使用隱式綁定和顯式綁定對this進(jìn)行修改
在這里介紹一種軟綁定的方法softBind(),檢查this綁定到全局對象或者undefined后,綁定this到指定的默認(rèn)對象。綁定后效果和硬綁定一樣,但是保留隱式綁定或者顯式綁定修改this的能力。

四、new綁定

Javascript中的new機(jī)制與面向類語言的完全不同。在Javascript中,構(gòu)造函數(shù)只是一些使用new操作符時(shí)被調(diào)用的函數(shù),不屬于一個(gè)類,也不會(huì)實(shí)例化一個(gè)類。稱為對函數(shù)的“構(gòu)造調(diào)用”。

舉個(gè)栗子:

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

使用new的過程會(huì)創(chuàng)建一個(gè)全新的對象,this會(huì)綁定這個(gè)新對象。如果函數(shù)沒有返回其他對象,則new表達(dá)式函數(shù)調(diào)用會(huì)返回該新對象。(這個(gè)新對象會(huì)連接prototype)

四種綁定規(guī)則的優(yōu)先級為:new>顯式>隱式>默認(rèn) 箭頭函數(shù)

箭頭函數(shù)是根據(jù)外層作用域(函數(shù)或全局)來決定this。(詞法作用域取代this機(jī)制)
箭頭函數(shù)this會(huì)綁定調(diào)用時(shí)的對象,且箭頭函數(shù)的綁定無法修改(new也不行)。

其實(shí)可以理解為,箭頭函數(shù)的this在詞法上繼承的是它所在的作用域(函數(shù)或全局)的this,而它繼承的函數(shù)作用域的this綁定的是在該函數(shù)調(diào)用上下文對象,所以箭頭函數(shù)的this間接的綁定在調(diào)用上下文對象。

簡述: 箭頭函數(shù)this(綁定作用域this)-- 作用域this(綁定在調(diào)用上下文對象)。

故:箭頭函數(shù)this == 調(diào)用的上下文對象

舉個(gè)栗子:

function foo() {
    setTimeout(function() {
        //這里的this在詞法上繼承自foo()
        console.log(this.a);
    },100);
};
var obj = { a: 2 };
foo.call(obj);  //2

其實(shí)這個(gè)栗子也等價(jià)于:

function foo() {
    var that = this;  //lexical capture of this
    setTimeout(function() {
        console.log(self.a)
    },100);
}
...與上面一樣

所以,有兩種風(fēng)格:this風(fēng)格(四種規(guī)則)詞法作用域風(fēng)格(that = this和箭頭函數(shù))可供使用。使用時(shí)盡量避免混用,否則會(huì)造成難以維護(hù)的后果。

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

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

相關(guān)文章

  • 我對JavaScriptthis一些理解

    摘要:匿名函數(shù)的執(zhí)行環(huán)境具有全局性,因此它的對象通常指向。如果對此有疑惑,可以看知乎上的答案知乎匿名函數(shù)的指向?yàn)槭裁词亲鳛閷ο蠓椒ǖ恼{(diào)用,指向該對象當(dāng)函數(shù)作為某個(gè)對象的方法調(diào)用時(shí),就指這個(gè)函數(shù)所在的對象。 因?yàn)槿粘9ぷ髦薪?jīng)常使用到this,而且在JavaScript中this的指向問題也很容易讓人混淆一部分知識(shí)。 這段時(shí)間翻閱了一些書籍也查閱了網(wǎng)上一些資料然后結(jié)合自己的經(jīng)驗(yàn),為了能讓自...

    focusj 評論0 收藏0
  • 理解 JavaScript this

    摘要:回調(diào)函數(shù)在回調(diào)函數(shù)中的指向也會(huì)發(fā)生變化。在閉包回調(diào)函數(shù)賦值等場景下我們都可以利用來改變的指向,以達(dá)到我們的預(yù)期。文章參考系列文章理解閉包理解執(zhí)行棧理解作用域理解數(shù)據(jù)類型與變量原文發(fā)布在我的公眾號(hào),點(diǎn)擊查看。 這是本系列的第 5 篇文章。 還記得上一篇文章中的閉包嗎?點(diǎn)擊查看文章 理解 JavaScript 閉包 。 在聊 this 之前,先來復(fù)習(xí)一下閉包: var name = Nei...

    zombieda 評論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)問題 講解this指針的原理是個(gè)很復(fù)雜的問題,如果我們從javascript里this的實(shí)現(xiàn)機(jī)制來說明this,很多朋友可能會(huì)越來越糊涂,因此本篇打算換一個(gè)思路從應(yīng)用的角度來講解this指針,從這個(gè)角度理解this指針更加有現(xiàn)實(shí)意義。 下面我們看看在ja...

    ghnor 評論0 收藏0
  • 加深對 JavaScript This 理解

    摘要:使用來調(diào)用函數(shù),會(huì)自動(dòng)執(zhí)行下面操作創(chuàng)建一個(gè)全新的對象。所以如果是一個(gè)函數(shù)的話,會(huì)是這樣子的創(chuàng)建一個(gè)新對象連接新對象與函數(shù)的原型執(zhí)行函數(shù),改變指向新的對象所以,在使用來調(diào)用函數(shù)時(shí)候,我們會(huì)構(gòu)造一個(gè)新對象并把它綁定到函數(shù)調(diào)用中的上。 歡迎來我的博客閱讀:《加深對 JavaScript This 的理解》 我相信你已經(jīng)看過很多關(guān)于 JavaScript 的 this 的談?wù)摿耍热荒泓c(diǎn)進(jìn)來...

    PiscesYE 評論0 收藏0
  • 理解 JavaScript call()/apply()/bind()

    摘要:理解文章中已經(jīng)比較全面的分析了在中的指向問題,用一句話來總結(jié)就是的指向一定是在執(zhí)行時(shí)決定的,指向被調(diào)用函數(shù)的對象。與和直接執(zhí)行原函數(shù)不同的是,返回的是一個(gè)新函數(shù)。這個(gè)新函數(shù)包裹了原函數(shù),并且綁定了的指向?yàn)閭魅氲摹? 理解 JavaScript this 文章中已經(jīng)比較全面的分析了 this 在 JavaScript 中的指向問題,用一句話來總結(jié)就是:this 的指向一定是在執(zhí)行時(shí)決定的,...

    duan199226 評論0 收藏0
  • javascriptthis理解

    摘要:的關(guān)鍵字總是讓人捉摸不透,關(guān)鍵字代表函數(shù)運(yùn)行時(shí),自動(dòng)生成的一個(gè)內(nèi)部對象,只能在函數(shù)內(nèi)部使用,因?yàn)楹瘮?shù)的調(diào)用場景不同,的指向也不同。其實(shí)只要理解語言的特性就很好理解。個(gè)人對中的關(guān)鍵字的理解如上,如有不正,望指正,謝謝。 javascript的this關(guān)鍵字總是讓人捉摸不透,this關(guān)鍵字代表函數(shù)運(yùn)行時(shí),自動(dòng)生成的一個(gè)內(nèi)部對象,只能在函數(shù)內(nèi)部使用,因?yàn)楹瘮?shù)的調(diào)用場景不同,this的指向也不...

    jimhs 評論0 收藏0

發(fā)表評論

0條評論

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