成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

淺談 javascript 中的this綁定問題

duan199226 / 1668人閱讀

摘要:綁定使用方式進(jìn)行調(diào)用函數(shù)時(shí),會發(fā)生構(gòu)造函數(shù)的調(diào)用。先上圖,然后根據(jù)文字閱讀使用調(diào)用函數(shù)之后,該函數(shù)才作為構(gòu)造函數(shù)進(jìn)行調(diào)用,構(gòu)造一個(gè)全新的對象賦值給,而對象的指向了的對象,的對象有一個(gè)屬性指向的構(gòu)造函數(shù)這個(gè)就是的原型鏈,也是的特性。

javascript語言是在運(yùn)行時(shí)前即進(jìn)行編譯的,而this的綁定也是在運(yùn)行時(shí)進(jìn)行綁定的。也就是說,this實(shí)際上是在函數(shù)被調(diào)用時(shí)候發(fā)生綁定的,它指向什么完全取決于函數(shù)在哪里被調(diào)用。

1.默認(rèn)綁定

例如直接在全局作用域下聲明:

var a=2;
console.log(this.a);

在全局作用域下聲明的變量或者函數(shù)等,都會作為window對象的屬性。

這個(gè)時(shí)候,默認(rèn)this是綁定到全局作用域下的window對象,如果你去console.log(this);你會發(fā)現(xiàn),你打印出來的是window,盡管你沒有聲明this就是window,但是js進(jìn)行了默認(rèn)綁定。

以至于你運(yùn)行以下的代碼片段:
function foo(){
console.log(this.a);
}
var a=2;
foo();
瀏覽器控制臺打印出來的是 2 ;

2.隱式綁定

當(dāng)函數(shù)引用有上下文對象時(shí),在函數(shù)調(diào)用時(shí),會進(jìn)行隱式綁定。這么說肯定很抽象,還是舉例說明吧。
var a=4;
function foo(){
console.log(this.a);
}
var obj={
  a:2,
  foo:foo
}
foo();
obj.foo();
兩次會打印出來什么呢?猜一下?

foo()會打印出來4,obj.foo()會打印出來2

第一個(gè)foo() 使用了默認(rèn)綁定,this綁定到了全局對象window,打印 this.a 就是打印window.a;

第二個(gè)foo()外層的foo函數(shù)引用作為obj.foo的屬性值,通過obj進(jìn)行調(diào)用,此時(shí)的obj就是這個(gè)函數(shù)引用的上下文對象,this會隱式綁定到obj這個(gè)對象上。此時(shí)打印的this.a就是obj.a了。

3.顯式綁定

在上面兩種綁定中,我們都沒有去明確地進(jìn)行強(qiáng)制綁定,而是使用了默認(rèn)規(guī)則的綁定,那么如果我們想要在調(diào)用某個(gè)函數(shù)時(shí)特定地改變this的綁定,這個(gè)時(shí)候就可以用顯式綁定了。

還是上代碼,然后進(jìn)行分析。

var a=4;
function foo(){
console.log(this.a);
}
var obj={
  a:2,
  foo:foo
}
var foo1=foo.bind(obj);
foo();
foo.call(obj);
foo.apply(obj);
foo.call(window);
foo1();
按照順序打印出的是 4 ,2 ,2, 4,2

第一次打印了4 使用了默認(rèn)綁定,foo函數(shù)的this綁定到了window。

第二次打印了2 使用了call函數(shù),顯式地將foo函數(shù)的this綁定到obj對象。

第三次打印了2 apply方法的效果跟call方法一樣。

第四次打印了4 call方法顯示地將foo函數(shù)的this綁定到了obj對象,效果跟默認(rèn)綁定一樣了。

第五次打印了2,bind方法顯示地將foo函數(shù)的this綁定到了obj,并且返回了一個(gè)硬編碼后的新函數(shù),賦值給foo1變量進(jìn)行調(diào)用,硬編碼就是新函數(shù)內(nèi)部this直接綁定到了指定的對象,也就是obj。

4.new 綁定

使用new方式進(jìn)行調(diào)用函數(shù)時(shí),會發(fā)生構(gòu)造函數(shù)的調(diào)用。怎么解釋呢,還是直接上代碼加分析。
function foo(a){
 this.a=a;
}
foo(3);
var test=new foo(2);
console.log(a);
console.log(test.a);
打印出來的是 3 ,2

foo函數(shù)只是一個(gè)普通的函數(shù),直接調(diào)用foo(3)只是作為普通函數(shù)的調(diào)用,會使用默認(rèn)綁定將this綁定到window上,對window.a也就會全局變量a進(jìn)行賦值,所以打印出來的是3;

foo函數(shù),進(jìn)行構(gòu)造調(diào)用,this綁定到test對象,故而this.a作為test對象的屬性并進(jìn)行傳參賦值。打印出來的test就是{a:2},this.a就是2了。

先上圖,然后根據(jù)文字閱讀

使用new 調(diào)用函數(shù)之后,該foo函數(shù)才作為構(gòu)造函數(shù)進(jìn)行調(diào)用,構(gòu)造一個(gè)全新的對象賦值給test,而test對象的_proto_
指向了test的prototype對象,test的prototype對象有一個(gè)屬性constructor,指向test的構(gòu)造函數(shù)foo,這個(gè)就是javascript的原型鏈,也是javascript的特性。對于test對象調(diào)用的方法以及屬性,會先在test對象進(jìn)行尋找,如果找到的話,就直接進(jìn)行調(diào)用,尋找停止。如果尋找不到,順著原型鏈,在test對象的prototype對象尋找,如果找到的話,進(jìn)行調(diào)用,尋找停止,如果還是找不到,會在prototype對象的原型上進(jìn)行尋找,這個(gè)時(shí)候_proto_指向了Object的prototype對象,Object的prototype的constructor指向了Object()本身,而一些Obejct的函數(shù)如toString等等就是在這個(gè)原型上進(jìn)行調(diào)用的,這個(gè)時(shí)候如果還是找不到需要屬性或者方法,那么就是語法錯(cuò)誤,未定義了。因?yàn)镺bject的prototype的_proto_指向是null了,也就沒有任何對象屬性以及方法了。

不是說程序員可以new 很多個(gè)對象嘛,但是new出來的對象 原型最終結(jié)果卻是指向了 空(null),所以還是自己動手豐衣足食吧,哈哈。

一般情況下,使用new函數(shù)之后構(gòu)造的對象,會優(yōu)先將函數(shù)調(diào)用到的this綁定到這個(gè)對象,如果函數(shù)沒有返回其它對象,會自動調(diào)用返回這個(gè)新對象。

總結(jié):

只有對于this綁定的情況有了基本的了解,才能在編寫代碼時(shí)候,避免產(chǎn)生由于綁定帶來的未知bug。如果你在調(diào)用某個(gè)框架插件或者綁定事件的時(shí)候,發(fā)現(xiàn)this不好用了,有可能是你的this使用綁定錯(cuò)了,打印下console.log(this)在控制臺看一看,也許就發(fā)現(xiàn)問題了。

如果在閱讀中遇到什么問題,歡迎評論以及留言。同時(shí)歡迎我的博客陳建光的博客

歡迎評論以及留言,同時(shí)歡迎關(guān)注我的博客定時(shí)不斷地更新我的文章 陳建光的博客

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

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

相關(guān)文章

  • 淺談React事件機(jī)制

    摘要:事件簡介事件是合成事件,所有事件都自動綁定到最外層上。支持事件的冒泡機(jī)制,我們可以使用和來中斷它。這樣做簡化了事件處理和回收機(jī)制,效率也有很大提升。事件類型合成事件的事件類型是原生事件類型的一個(gè)子集。 React事件簡介 React事件是合成事件,所有事件都自動綁定到最外層上。因?yàn)閂irtual DOM 在內(nèi)存中是以對象的形式存在的,所以React 基于 Virtual DOM 實(shí)現(xiàn)了...

    moven_j 評論0 收藏0
  • 淺談React事件機(jī)制

    摘要:事件簡介事件是合成事件,所有事件都自動綁定到最外層上。支持事件的冒泡機(jī)制,我們可以使用和來中斷它。這樣做簡化了事件處理和回收機(jī)制,效率也有很大提升。事件類型合成事件的事件類型是原生事件類型的一個(gè)子集。 React事件簡介 React事件是合成事件,所有事件都自動綁定到最外層上。因?yàn)閂irtual DOM 在內(nèi)存中是以對象的形式存在的,所以React 基于 Virtual DOM 實(shí)現(xiàn)了...

    MyFaith 評論0 收藏0
  • 淺談-this

    摘要:回調(diào)函數(shù)中調(diào)用在回調(diào)函數(shù)中一般有兩種情況回調(diào)函數(shù)為匿名函數(shù)時(shí),回調(diào)函數(shù)的會指向,需要對回調(diào)函數(shù)?;卣{(diào)函數(shù)為箭頭函數(shù)時(shí),回調(diào)函數(shù)的會指向他的直接上層。 淺談-this this簡單而又神秘,使用場景多變而又復(fù)雜,這造就了它成為了初級javascript開發(fā)人員不愿接觸的東西,高級javascript都想探究的東西。文本亦是對this的致敬。 this是什么? this是當(dāng)前執(zhí)行環(huán)境...

    archieyang 評論0 收藏0
  • 淺談javascript里面的this、call、apply、bind

    摘要:如果該參數(shù)的值為或,則表示不需要傳入任何參數(shù),從開始可以使用類數(shù)組對象。當(dāng)使用操作符調(diào)用綁定函數(shù)時(shí),該參數(shù)無效。當(dāng)綁定函數(shù)被調(diào)用時(shí),這些參數(shù)將置于實(shí)參之前傳遞給被綁定的方法。 在了解call,apply之前需要先了解下javascrit中this指向 this的指向在ES5里面,this永遠(yuǎn)指向最后調(diào)用它的那個(gè)對象舉個(gè)栗子: var name = outerName; function...

    Lemon_95 評論0 收藏0
  • 淺談Javascript閉包中作用域及內(nèi)存泄漏問題

    摘要:將作用域賦值給變量這里的作用域是,而不是將作用域賦值給一個(gè)變量閉包返回瀏覽器中內(nèi)存泄漏問題大家都知道,閉包會使變量駐留在內(nèi)存中,這也就導(dǎo)致了內(nèi)存泄漏。 上一章我們講了匿名函數(shù)和閉包,這次我們來談?wù)勯]包中作用域this的問題。 大家都知道,this對象是在運(yùn)行時(shí)基于函數(shù)的執(zhí)行環(huán)境綁定的,如果this在全局就是[object window],如果在對象內(nèi)部就是指向這個(gè)對象,而閉包卻是在運(yùn)行...

    source 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<