小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

談"this"

 Coder編程 2021-09-10

  首先,很多人對(duì)this有兩個(gè)誤解

  1.this指向的是當(dāng)前函數(shù)本身

  什么意思呢,下面看一段代碼。

 1 function func(){
 2     this.a ++;
 3 }
 4             
 5 var a = 0;
 6 func.a = 0;
 7             
 8 for(let i = 0; i < 5; i++){
 9     func();
10 }
11             
12 console.log(a);  //->5
13 console.log(func.a);//->0

    發(fā)現(xiàn)問題了,因?yàn)楹瘮?shù)本身也是一個(gè)對(duì)象,如果this指向的是當(dāng)前函數(shù)本身,那么在調(diào)用func函數(shù)5次后,func.a應(yīng)該輸出的是5,但是程序結(jié)果輸出的是0,但是全局定義的a變量輸出了結(jié)果5,顯然在這里函數(shù)中this指向的不是函數(shù)本身,而指向了全局對(duì)象.

    這是為什么呢?接著往下看。

   

  2.this指向的是當(dāng)前函數(shù)的作用域

  先看一段代碼:

function foo(){
    var a = 0;
    this.bar();          
}

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

foo();//->undefined

 

  這段代碼在按照“this指向的是當(dāng)前函數(shù)的作用域”這樣的理解下,在理想的執(zhí)行狀態(tài)下是這樣子的:

//foo();

function foo(){
    var a = 0;
    console.log(a);  
}

  因?yàn)榘凑丈衔睦斫猓瑃his指向的是當(dāng)前的函數(shù)作用域,所以這段代碼能夠執(zhí)行成功是有問題的,如果this指向的是當(dāng)前的函數(shù)作用域,foo函數(shù)的詞法作用域中并沒有一個(gè)標(biāo)識(shí)符為bar的函數(shù);

  在嚴(yán)格模式下,這段代碼是無法執(zhí)行的(報(bào)錯(cuò))。

  

  

  this到底是一個(gè)什么樣的機(jī)制呢?那么這里下一個(gè)定義:this的指向是取決于函數(shù)調(diào)用的方式,跟函數(shù)怎么寫沒有半毛錢關(guān)系。this的指向并沒有在編寫代碼的時(shí)候就綁定了,而發(fā)生在函數(shù)的調(diào)用時(shí)。

  當(dāng)一個(gè)函數(shù)被調(diào)用時(shí),會(huì)創(chuàng)建一個(gè)活動(dòng)記錄(執(zhí)行上下文)。這個(gè)記錄會(huì)包含函數(shù)在哪里被調(diào)用(調(diào)用棧)、函數(shù)的調(diào)用方式、傳入的參數(shù)等信息。this就是這個(gè)記錄的一個(gè)屬性,會(huì)在函數(shù)執(zhí)行的過程中用到。

  

函數(shù)調(diào)用位置的追蹤:

function baz(){
    //當(dāng)前的調(diào)用棧是:baz
    //因此,當(dāng)前調(diào)用位置是全局作用域

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

function bar(){
    //當(dāng)前調(diào)用棧是:baz -> bar
    //因此,當(dāng)前調(diào)用位置在baz中
    console.log("bar");
    foo();  // <-- foo的調(diào)用位置  
}

function foo(){
    //當(dāng)前的調(diào)用棧是:baz -> bar -> foo
    //因此,當(dāng)前的調(diào)用位置在bar中
    console.log("foo");    
}

baz();  //<-- baz的調(diào)用位置

 

既然this的綁定取決于函數(shù)的調(diào)用方式,那么this存在下面這四種綁定規(guī)則:

  • 默認(rèn)綁定
  • 隱式綁定
  • 顯示綁定
  • new綁定

 

默認(rèn)綁定簡單地來講,默認(rèn)綁定就是單獨(dú)的,沒有任何修飾符的函數(shù)調(diào)用,就像這樣。

foo();

這時(shí),this指向全局對(duì)象,下面給這個(gè)函數(shù)加上this來試一試。

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

var num = 6;

foo(); //->6

但是,只有在非嚴(yán)格模式下,this在默認(rèn)綁定下才能綁定到全局對(duì)象上;如果在嚴(yán)格模式下,this會(huì)綁定到undefined。

記住了,就光寫一個(gè)光禿禿的函數(shù)調(diào)用,就是默認(rèn)綁定,這時(shí)this指向的是全局對(duì)象(在非嚴(yán)格模式下)。

 

隱式綁定:又是簡單地來講,隱式綁定就是當(dāng)這個(gè)函數(shù)作為某個(gè)對(duì)象的方法被調(diào)用時(shí),this就會(huì)指向這個(gè)對(duì)象。

 

obj.foo();

 

考慮一下調(diào)用的位置是否有上下文對(duì)象,就是說這個(gè)函數(shù)是否被某個(gè)對(duì)象擁有或包含。

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

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

obj.foo(); // -> 2 這時(shí)foo函數(shù)的this指向obj這個(gè)對(duì)象

因?yàn)檫@時(shí)this函數(shù)指向的就是包含它的obj對(duì)象,所以此時(shí)this.a === obj.a 

這就叫做隱式綁定,不過隱式綁定有一個(gè)問題,最常見的問題就是被隱式綁定的函數(shù)會(huì)丟失綁定對(duì)象,怎么回事呢,來看一下下面的代碼:

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

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

var bar = obj.foo;

var a = "global";  //a是全局對(duì)象的屬性

bar();  // -> "global"

看到?jīng)]?本來foo應(yīng)該指向obj來著,現(xiàn)在指向了全局對(duì)象,是怎么回事呢?那是因?yàn)閛bj的方法foo作為一個(gè)單獨(dú)的函數(shù)被賦值給了bar,bar就成了foo函數(shù)的別名,輸出一下bar,看看里面是什么:

這里可以看到,bar的內(nèi)容是foo函數(shù)的函數(shù)體,所以這里調(diào)用bar,與foo()語句等價(jià),使用了默認(rèn)綁定,this指向全局對(duì)象,所以才會(huì)輸出"global",在編程中,要注意這個(gè)細(xì)節(jié)。

 

顯式綁定:顯式綁定說白了就是函數(shù)使用call方法或apply顯式地指定了this的指向。

例如:

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

var obj = {
    a : 2
};

foo.call( obj );  //->2

說到了call和apply,他倆也沒啥區(qū)別,只是調(diào)用時(shí)寫法有點(diǎn)不一樣:

func.call(this, arg1, arg2);
func.apply(this, [arg1, arg2]);

call的函數(shù)參數(shù)一直寫,中間用逗號(hào)隔開,apply的函數(shù)參數(shù)以數(shù)組形式給出。

 

new綁定:這個(gè)就不用說了,在用new調(diào)用函數(shù)時(shí),函數(shù)內(nèi)的this指向當(dāng)前對(duì)象。

在JavaScript中,沒有明顯的標(biāo)識(shí)符什么的說明構(gòu)造函數(shù)是構(gòu)造函數(shù),實(shí)際上,Javascript不存在構(gòu)造函數(shù),只有被“構(gòu)造調(diào)用”的普通函數(shù)。new關(guān)鍵字將一個(gè)普通函數(shù)“構(gòu)造調(diào)用”,并且將這個(gè)普通函數(shù)的this與創(chuàng)建的對(duì)象相關(guān)聯(lián)。

 

function Person( name, sex ){
    this.name = name;
    this.sex = sex;
}

// -> Person的this現(xiàn)在指向xiaoming
var xiaoming = new Person("小明","男");  

 

 

那么基本的this指向問題就這么簡單地說完了,總結(jié)一下,this的指向其實(shí)跟函數(shù)如何編寫沒有什么關(guān)系,只跟函數(shù)調(diào)用的方式有關(guān)系。希望這篇文章可以幫到大家更好地理解this的問題,如果有補(bǔ)充或者疑問,請(qǐng)?jiān)谠u(píng)論區(qū)留言,謝謝!

 

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多