作用域js和java区别_js作用域理解
學習筆記:(圖中水印來自同名微信訂閱號,現已改名為‘碼上猿夢’)
//javaScript作用域:
//首先聲明一點,js中沒有塊級作用域,
比如java中for循環中for(int i = 0; i < arr.length; i++){}中的變量i只能在for循環的大括號內部能訪問,
//但是在js中,for(var i = 0; i < arr.length; i++){},i的作用域是包含了這個for循環的函數的作用域,或者是全局作用域.
1.全局作用域
(1).最外層函數和定義在最外層函數外面的變量具有全局作用域:
(2).沒有使用var關鍵字聲明變量
上面的代碼等價于下面的代碼:(沒有使用var關鍵字聲明的a自動變為全局變量)
//2.局部作用域
//與全局作用域相反,局部作用域就是聲明定義在函數內部的變量或者函數,他們擁有局部作用域,也叫函數作用域,
//這些變量也叫局部變量,這些變量只能在聲明定義他們的函數里面訪問,
//作用域鏈:之前學過java, 目前在自學c#和javaScript, 學js才發現在js中真的是萬物皆對象: 在普通代碼中表現的比在java和c#中更加徹底. C#中的委托將函數名作為對象當成參數傳遞, java中也有這樣的 , 那就反射. js中所有的東西都是對象, 函數也是對象, 它具有屬性和方法, ( 在java中函數也可以說是方法, 但在js中這樣說函數比較恰當,因為函數也是具有方法的. )
//函數和其他對象一樣, 擁有可以通過代碼訪問的屬性和一系列僅供js引擎訪問的內部屬性, 其中有一個內部屬性就是作用域鏈 [[scope]] , 這個內部屬性包含了函數被創建時函數作用域中所有對象 ( 函數里面的函數也是對象 ) 的集合, 這個集合被稱為函數的作用域鏈, 它決定了哪些數據能夠被這個函數訪問. 每個函數都會有這樣一個作用域鏈, 這樣一來就會有很多個不同作用域鏈,
[[scope]] 里面存放的只是一個地址, 也就是Scope chain的地址,[[scope]]指向了Scope chain,Scope chain是一個鏈表結構,里面存放著各種函數作用域,其中也包括全局作用域,
//程序還沒有執行的時候,這個鏈表的最頂端存放的是全局作用域,比如這段代碼:
當函數被創建的時候,它的作用域鏈就會填入一個全局對象,這個全局對象包含了所有的全局變量,(只列舉了部分變量)
如下圖:
//如果開始執行add函數,
var total = add(5, 10);
//那么這個鏈表的最頂端一定是當前正在執行的函數的函數作用域(是函數作用域,不是作用域鏈),全局作用域自然在第二層了(其實在這里我在想,這里的鏈表是不是棧,這點我沒有想明白,留一個疑問吧,以后再思考)
//補充一點:當執行流進入一個函數時,也就是一個函數要被執行時,會創建一個"運行時期上下文(execution context)"的執行環境,這也是一個內部對象, 這個運行時期上下文也是一個作用域鏈, 也是包含著該函數作用域中所有的對象, 運行時期上下文作用域鏈是由之前這個函數的作用域鏈初始化的, 然后js引擎又會去創建一個活動對象(Active Object),這個活動對象包含了函數運行期所有的局部變量,參數以及this等變量,
如下圖:
//這個活動對象用于標識符的解析,也就是當你要使用一個變量時,活動對象會去它的作用域鏈中的一個個函數作用域去遍歷尋找該變量的標識符,如果找到了就使用這個標識符對應的變量,
如果沒有找到,那就向下遍歷另一個函數作用域,直到找到為止,但是如果一直遍歷到了全局作用域都沒有找到和該標識符的定義,那就好吧,我給你報錯.
(而且每個標識符都要經歷這個遍歷尋找的過程,所以盡量少使用全局變量,而應該多使用局部變量,有一個好的經驗法則就是:如果一個跨作用域的對象被使用了一次以上,那就把它存儲在局部作用域里再使用,這樣也能減少代碼量,但最重要的是提高了程序的性能.比如document這個全局變量,)
以上代碼文字均手敲測試過,如有錯誤請指出,謝謝啦~~
歡迎關注同名微信訂閱號:碼上猿夢
筆記參考自夢想天空的博客,
博客地址:http://www.cnblogs.com/lhb25/archive/2011/09/06/javascript-scope-chain.html
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的作用域js和java区别_js作用域理解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c linux time微秒_qt li
- 下一篇: java 学习代码库_java 学习4