摘要:一直以來的原型鏈和作用域鏈非常困擾我,其中夾雜著問題更是讓問題雪上加霜,并不是說原型鏈或者說作用域鏈有多難理解,而是經常混亂了概念,下面記錄一下思考過程,希望對自己或是他人都有幫助。
一直以來JavaScript的原型鏈和作用域鏈非常困擾我,其中夾雜著this問題更是讓問題雪上加霜,并不是說原型鏈或者說作用域鏈有多難理解,而是經常混亂了概念,下面記錄一下思考過程,希望對自己或是他人都有幫助。
var maybe="maybe" function ObjectMake (){ var maybe = "hello"; this.getmaybe = function(){ return maybe; } } var b = new ObjectMake(); var c = b.getmaybe(); //hello
作用域(scope)是針對函數而言的,每個函數在執行的時候都會分配作用域鏈,上面例子是一個典型的工廠模式,其中對于ObjectMake函數而言,其作用域鏈[[scope]]是scope_0(Windows)+scope_1(ObjectMake),對于getmaybe函數而言,其作用域是scope_0(Windows)+scope_1(ObjectMake)+scope_2(getmaybe),在scope0和scope1都存在maybe變量的時候,scope1優先于scope0,所以變量c的值是hello。
下面這種情況呢:
var maybe="maybe"; var getmaybe = function(){ return maybe; } function ObjectMake (){ var maybe = "hello"; this.getmaybe = getmaybe; } var b = new ObjectMake(); var c = b.getmaybe(); //maybe 根據作用域鏈分析可以得出:對于getmaybe函數而言,其作用域鏈[[scope]]是scope_0(Windows)+scope_1(getmaybe),對于對于ObjectMake函數而言,其作用域鏈[[scope]]是scope_0(Windows)+scope_1(ObjectMake),所以當運行b.getmaybe時getmaybe查找作用域只能在cope_0(Windows)中發現maybe變量,故c的值為maybe。 有人可能會提出一個問題,為什么getmaybe函數作用域鏈沒有包含scope_1(ObjectMake),因為JavaScript是詞法作用域,簡而言之,就是函數的作用域鏈只和函數在哪里定義有關系,和函數在哪里運行沒有關系,上面getmaybe定義在Windows中,所以其作用域鏈中只存在兩個:Windows和它自己。 明白了這個道理,下面這個例子又讓我暈了很久: var maybe = "maybe"; var show = { maybe:"hello", getmaybe:function(){ return maybe; } } var d = show.getmaybe();//maybe 按照之前的說法,getmaybe定義在對象show對象當中,為何d的值不是maybe?讓我們還是從之前的分析作用域鏈開始,函數getmaybe定義在對象show中,其作用域鏈為:scope_0(Windows)+scope_(getmaybe),scope作用域代表獲取執行環境的地址,目前JavaScript的執行環境有:1)全局執行環境、2)Eval函數執行環境、3)普通函數執行環境,可知show對象不是一個執行環境,函數的scope無法將它推入作用域鏈中,所以d的值為maybe。 下面我們再看一個例子: var maybe = "maybe"; var show = { maybe:"hello", getmaybe:function(){ return this.maybe; } } var d = show.getmaybe();//hello 上面在getmaybe函數中加上this指針后,終于返回了hello了,this指針在JavaScript中是一個非常重要但是又常常會誤導人的概念,在一般的OOP(面向對象的語言中),一般都有this這個概念,比如c++的this,Python的self等等。this代表對象實例的地址,在JavaScript中,對象都是實例,不存在C++中的class概念,而this都是動態綁定的(可以用apply()或是call()等函數來改變),show.getmaybe()將getmaybe函數的this指針綁定了show對象,有些時候this指針會被偷偷的替換掉,這個時候可能我們都不知道,關于this指針,下次有時間再寫一篇作為理解之用。 這篇文章主要是關于JavaScript對象和作用域的關系,但實際上通過上面的例子可以知道,它們并沒有關系,都是個人見解,有誤后續會修改。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/86564.html
摘要:示例當一個函數創建后,它的作用域鏈會被創建此函數的作用域中可訪問的數據對象填充。每一個運行期上下文都和一個作用域鏈關聯。此時,作用域鏈中函數的所有局部變量所在的作用域對象會被推后,訪問代價變高了。 作用域 作用域就是變量與函數的可訪問范圍,即作用域控制著變量與函數的可見性和生命周期。在JavaScript中,變量的作用域有全局作用域和局部作用域兩種。 作用域鏈 函數對象有一個內部屬性[...
摘要:所以,全局執行環境的變量對象始終都是作用域鏈中的最后一個對象。講到這里,可能你已經對執行環境執行環境對象變量對象作用域作用域鏈的理解已經他們之間的關系有了一個較清晰的認識。 JavaScript中的執行環境、作用域、作用域鏈、閉包一直是一個非常有意思的話題,很多博主和大神都分享過相關的文章。這些知識點不僅比較抽象,不易理解,更重要的是與這些知識點相關的問題在面試中高頻出現。之前我也看過...
摘要:每一個運行期上下文都和一個作用域鏈關聯。這個對象將被推入作用域鏈的頭部,這意味著函數的所有局部變量現在處于第二個作用域鏈對象中,因此訪問代價更高了。在代碼塊內部,函數的所有局部變量將會被放在第二個作用域鏈對象中。 參考: Javascript作用域原理 理解 JavaScript 作用域和作用域鏈 JavaScript 作用域 作用域就是變量與函數的可訪問范圍,即作用域控制著變量與函數...
摘要:作用域與作用域鏈每個函數都有自己的執行環境。這是初步了解作用域,如想更深入了解作用域,請看下面鏈接作用域原理作用域鏈由一道題圖解的作用域或者看權威指南和高級程序設計 本文是我學習JavaScript作用域整理的筆記,如有不對,請多指出。 作用域 一個變量的作用域是程序源代碼中定義這個變量的區域。 而在ES5中只分為全局作用域和函數作用域,也就是說for,if,while等語句是不會創建...
摘要:當函數被調用的時候,作用域鏈就會包含多個作用域對象。但是當函數要訪問時,并沒有找到,于是沿著作用域鏈向上查找,在的作用域找到了對應的標示符,就會修改的值。 JS JavaScript閉包和作用域 閉包 JavaScript高級程序設計中對閉包的定義:閉包是指有權訪問另外一個函數作用域中變量的函數。 從概念上,閉包有兩個特點: 函數 能訪問另外一個函數的作用域中的變量 在ES6之前,...
摘要:變量對象也是有父作用域的。作用域鏈的頂端是全局對象。當函數被調用的時候,作用域鏈就會包含多個作用域對象。當函數要訪問時,沒有找到,于是沿著作用域鏈向上查找,在的作用域找到了對應的標示符,就會修改的值。 一、概要 對于閉包的定義(紅寶書P178):閉包就是指有權訪問另外一個函數的作用域中的變量的函數。 關鍵點: 1、閉包是一個函數 2、能夠訪問另外一個函數作用域中的變量 二、閉包特性 對...
閱讀 3689·2021-10-13 09:40
閱讀 3149·2021-10-09 09:53
閱讀 3551·2021-09-26 09:46
閱讀 1848·2021-09-08 09:36
閱讀 4248·2021-09-02 09:46
閱讀 1314·2019-08-30 15:54
閱讀 3179·2019-08-30 15:44
閱讀 1023·2019-08-30 11:06