国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

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

snowLu / 2665人閱讀

摘要:理解作用域高級程序設計中有說到對象是在運行時基于函數的執行環境綁定的在全局函數中,等于,而當函數被作為某個對象調用時,等于那個對象。指向與匿名函數沒有關系如果函數獨立調用,那么該函數內部的,則指向。

理解this作用域

《javascript高級程序設計》中有說到:

this對象是在運行時基于函數的執行環境綁定的:在全局函數中,this等于window,而當函數被作為某個對象調用時,this等于那個對象。不過,匿名函數具有全局性,因此this對象同常指向window

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

關于閉包經常會看到這么一道題:

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個匿名函數,可能你會認為這就是輸出值為The Window的原因

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

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())


可以發現,同樣是匿名函數,卻輸出了The Window, My Object

在作用域鏈中,執行函數時會創建一個稱為“運行期上下文(execution context)”的內部對象,運行期上下文定義了函數執行時的環境。

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

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

實踐是檢驗真理的唯一標準,讓我們用代碼測試一下

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())


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

函數執行環境影響了this作用域
new運算符對this作用域對影響

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

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


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

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

繼續寫代碼通過事實來說明

var a = 1   //函數作用域
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聲明的變量屬于函數作用域,let/const聲明的變量屬于塊級作用域

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

總結

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

相關知識點

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

如果我的文章對你有幫助,歡迎關注我的博客,JS/Python/算法系列,碼不停題!!!

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/104036.html

相關文章

  • JavaScript深入淺出

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

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

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

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

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

    oogh 評論0 收藏0
  • 這一次,我們換種姿勢學習 javascript

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

    zone 評論0 收藏0
  • 一道JS面試題所引發的"血案",透過現象尋本質,再從本質看現象

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

    QiShare 評論0 收藏0

發表評論

0條評論

snowLu

|高級講師

TA的文章

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