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

資訊專欄INFORMATION COLUMN

【Javascript】深入理解this作用域問題以及new/let/var/const對this作

snowLu / 2673人閱讀

摘要:理解作用域高級程序設(shè)計中有說到對象是在運行時基于函數(shù)的執(zhí)行環(huán)境綁定的在全局函數(shù)中,等于,而當(dāng)函數(shù)被作為某個對象調(diào)用時,等于那個對象。指向與匿名函數(shù)沒有關(guān)系如果函數(shù)獨立調(diào)用,那么該函數(shù)內(nèi)部的,則指向。

理解this作用域

《javascript高級程序設(shè)計》中有說到:

this對象是在運行時基于函數(shù)的執(zhí)行環(huán)境綁定的:在全局函數(shù)中,this等于window,而當(dāng)函數(shù)被作為某個對象調(diào)用時,this等于那個對象。不過,匿名函數(shù)具有全局性,因此this對象同常指向window

針對于匿名函數(shù)this具有全局性的觀點仍是有爭議的,可參考 https://www.zhihu.com/questio...

關(guān)于閉包經(jīng)常會看到這么一道題:

var name = "The Window";
    var object = {
        name : "My Object",
        getNameFunc : function(){
            return function(){
                return this.name;
            };
        }
    };
console.log(object.getNameFunc()());//result:The Window


在這里,getNameFunc return了1個匿名函數(shù),可能你會認為這就是輸出值為The Window的原因

但是,我們再來嘗試寫1個匿名函數(shù)

var name = "The Window";
 var object = {
  name : "My Object",
  getNameFunc : function(){
   return this.funAA;
  },
  funAA:function(){
   return this.name
  }
 };
 console.log(object.getNameFunc()(),object.funAA())


可以發(fā)現(xiàn),同樣是匿名函數(shù),卻輸出了The Window, My Object

在作用域鏈中,執(zhí)行函數(shù)時會創(chuàng)建一個稱為“運行期上下文(execution context)”的內(nèi)部對象,運行期上下文定義了函數(shù)執(zhí)行時的環(huán)境。

個人認為是因為函數(shù)被object.getNameFunc()調(diào)用,funAA的作用域鏈被初始化為undefined即window的[[Scope]]所包含的對象,導(dǎo)致輸出結(jié)果為window.name

對作用域鏈不是很了解的同學(xué),可以查看這邊文章【Javascript】深入理解javascript作用域與作用域鏈

實踐是檢驗真理的唯一標(biāo)準(zhǔn),讓我們用代碼測試一下

var name = "The Window";
 var object = {
  name : "My Object",
  getNameFunc : function(){
   return this.funAA();
  },
  funAA:function(){
   return this.name
  }
 };
console.log(object.getNameFunc(),object.funAA())


可以發(fā)現(xiàn),輸出了 My Object, My Object
getNameFunc仍為匿名函數(shù),但是return的是this.funAA(),此時,this.funAA變成了由object調(diào)用,驗證了我們之前的猜想:

函數(shù)執(zhí)行環(huán)境影響了this作用域
new運算符對this作用域?qū)τ绊?/b>

還是實踐出真理,我們先來寫一段代碼

var a = 2
function test(){
    this.a = 1
    console.log(window.a)
}
new test()
test()


可以看出輸出結(jié)果為2,1
new運算符改變了test函數(shù)內(nèi)this的作用域,改變的原理是通過在函數(shù)內(nèi)創(chuàng)建一個對象obj,并通過test.call(obj),執(zhí)行obj.test(),這樣test的父函數(shù)就變成了obj,test復(fù)制的是obj的作用域鏈,而不是window

function subNew(){
    var obj = {}
    var res = test.call(obj,...arguments)
}
subNew()   // 作用等于new test()
let/var/const對this作用域的影響

繼續(xù)寫代碼通過事實來說明

var a = 1   //函數(shù)作用域
let b =1   //塊級作用域
const c = 1   //塊級作用域

function fn(){
    this.a = 2
    this.b = 2
    this.c =2
    console.log(this.a,this.b,this.c)
    console.log(a,b,c)
    //this指向全局作用域  this === window //true
}
fn()

var聲明的變量屬于函數(shù)作用域,let/const聲明的變量屬于塊級作用域

可以發(fā)現(xiàn),全局作用域中的a變量被改變,b變量與c變量都沒有被改變,說明在fn()中通過this訪問不到window作用域中的b/c變量
注:這里說的訪問不到與const定義的變量是常量沒有關(guān)系,因為如果訪問到的話,是會報typeError的

總結(jié)

1.this的指向取決于函數(shù)執(zhí)行時所創(chuàng)建運行期上下文(execution context)的內(nèi)部對象,它與當(dāng)前運行函數(shù)的[[scope]]所包含的對象組成了1個新的對象,這個對象就是活動對象,然后此對象會被推入作用域鏈的前端
2.如果調(diào)用的函數(shù),被某一個對象所擁有,那么該函數(shù)在調(diào)用時,內(nèi)部的this指向該對象。
3.this指向與匿名函數(shù)沒有關(guān)系,如果函數(shù)獨立調(diào)用,那么該函數(shù)內(nèi)部的this,則指向undefined。但是在非嚴(yán)格模式中,當(dāng)this指向undefined時,它會被自動指向全局對象。
4.在作用域鏈中,var定義的變量屬于函數(shù)作用域,可以被子級作用域下的this訪問,而let/const定義的變量屬于塊級作用域,不允許在其子級作用域中被訪問

相關(guān)知識點

不理解new的實踐可以查看我的這篇文章【Javascript】徹底捋清楚javascript中 new 運算符的實現(xiàn)
對作用域鏈不是很了解的同學(xué),可以查看這邊文章【Javascript】深入理解javascript作用域與作用域鏈

如果我的文章對你有幫助,歡迎關(guān)注我的博客,JS/Python/算法系列,碼不停題!?。?/h5>

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

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

相關(guān)文章

  • JavaScript深入淺出

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

    blair 評論0 收藏0
  • 深入理解JavaScript系列1:編寫高質(zhì)量JavaScript代碼的基本要點

    摘要:訪問全局對象在瀏覽器中,全局對象可以通過屬性在代碼的任何位置訪問除非你做了些比較出格的事情,像是聲明了一個名為的局部變量。 前言 才華橫溢的Stoyan Stefanov,在他寫的由O’Reilly初版的新書《JavaScript Patterns》(JavaScript模式)中,我想要是為我們的讀者貢獻其摘要,那會是件很美妙的事情。具體一點就是編寫高質(zhì)量JavaScript的一些要素...

    Enlightenment 評論0 收藏0
  • 深入javascript——和閉包

    摘要:注意由于閉包會額外的附帶函數(shù)的作用域內(nèi)部匿名函數(shù)攜帶外部函數(shù)的作用域,因此,閉包會比其它函數(shù)多占用些內(nèi)存空間,過度的使用可能會導(dǎo)致內(nèi)存占用的增加。 作用域和作用域鏈?zhǔn)莏avascript中非常重要的特性,對于他們的理解直接關(guān)系到對于整個javascript體系的理解,而閉包又是對作用域的延伸,也是在實際開發(fā)中經(jīng)常使用的一個特性,實際上,不僅僅是javascript,在很多語言中都...

    oogh 評論0 收藏0
  • 這一次,我們換種姿勢學(xué)習(xí) javascript

    摘要:操作符或調(diào)用函數(shù)時傳入?yún)?shù)的操作都會導(dǎo)致關(guān)聯(lián)作用域的賦值操作。此外可以使用和來設(shè)置對象及其屬性的不可變性級別。忽視這一點會導(dǎo)致許多問題。使用調(diào)用函數(shù)時會把新對象的屬性關(guān)聯(lián)到其他對象。 前言 《你不知道的 javascript》是一個前端學(xué)習(xí)必讀的系列,讓不求甚解的JavaScript開發(fā)者迎難而上,深入語言內(nèi)部,弄清楚JavaScript每一個零部件的用途。本書介紹了該系列的兩個主題:...

    zone 評論0 收藏0
  • 一道JS面試題所引發(fā)的"血案",透過現(xiàn)象尋本質(zhì),再從本質(zhì)看現(xiàn)象

    摘要:一看這二逼就是周杰倫的死忠粉看看控制臺輸出,確實沒錯就是對象。從根本上來說,作用域是基于函數(shù)的,而執(zhí)行環(huán)境是基于對象的例如全局執(zhí)行環(huán)境即全局對象。全局對象全局屬性和函數(shù)可用于所有內(nèi)建的對象。全局對象只是一個對象,而不是類。 覺得本人寫的不算很爛的話,可以登錄關(guān)注一下我的GitHub博客,博客會堅持寫下去。 今天同學(xué)去面試,做了兩道面試題,全部做錯了,發(fā)過來給我看,我一眼就看出來了,因為...

    QiShare 評論0 收藏0

發(fā)表評論

0條評論

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