摘要:作用域作用域是指程序源代碼中定義變量的區(qū)域。采用詞法作用域,也就是靜態(tài)作用域。而與詞法作用域相對(duì)的是動(dòng)態(tài)作用域,函數(shù)的作用域是在函數(shù)調(diào)用的時(shí)候才決定的。前面我們已經(jīng)說了,采用的是靜態(tài)作用域,所以這個(gè)例子的結(jié)果是。
作用域JavaScript深入系列的第二篇,JavaScript采用詞法作用域,什么語言采用了動(dòng)態(tài)作用域?兩者的區(qū)別又是什么?還有一個(gè)略難的思考題,快來看看吧。
作用域是指程序源代碼中定義變量的區(qū)域。
作用域規(guī)定了如何查找變量,也就是確定當(dāng)前執(zhí)行代碼對(duì)變量的訪問權(quán)限。
JavaScript 采用詞法作用域(lexical scoping),也就是靜態(tài)作用域。
靜態(tài)作用域與動(dòng)態(tài)作用域因?yàn)?JavaScript 采用的是詞法作用域,函數(shù)的作用域在函數(shù)定義的時(shí)候就決定了。
而與詞法作用域相對(duì)的是動(dòng)態(tài)作用域,函數(shù)的作用域是在函數(shù)調(diào)用的時(shí)候才決定的。
讓我們認(rèn)真看個(gè)例子就能明白之間的區(qū)別:
var value = 1; function foo() { console.log(value); } function bar() { var value = 2; foo(); } bar(); // 結(jié)果是 ???
假設(shè)JavaScript采用靜態(tài)作用域,讓我們分析下執(zhí)行過程:
執(zhí)行 foo 函數(shù),先從 foo 函數(shù)內(nèi)部查找是否有局部變量 value,如果沒有,就根據(jù)書寫的位置,查找上面一層的代碼,也就是 value 等于 1,所以結(jié)果會(huì)打印 1。
假設(shè)JavaScript采用動(dòng)態(tài)作用域,讓我們分析下執(zhí)行過程:
執(zhí)行 foo 函數(shù),依然是從 foo 函數(shù)內(nèi)部查找是否有局部變量 value。如果沒有,就從調(diào)用函數(shù)的作用域,也就是 bar 函數(shù)內(nèi)部查找 value 變量,所以結(jié)果會(huì)打印 2。
前面我們已經(jīng)說了,JavaScript采用的是靜態(tài)作用域,所以這個(gè)例子的結(jié)果是 1。
動(dòng)態(tài)作用域也許你會(huì)好奇什么語言是動(dòng)態(tài)作用域?
bash 就是動(dòng)態(tài)作用域,不信的話,把下面的腳本存成例如 scope.bash,然后進(jìn)入相應(yīng)的目錄,用命令行執(zhí)行 bash ./scope.bash,看看打印的值是多少。
value=1 function foo () { echo $value; } function bar () { local value=2; foo; } bar
這個(gè)文件也可以在github博客倉庫中找到。
思考題最后,讓我們看一個(gè)《JavaScript權(quán)威指南》中的例子:
var scope = "global scope"; function checkscope(){ var scope = "local scope"; function f(){ return scope; } return f(); } checkscope();
var scope = "global scope"; function checkscope(){ var scope = "local scope"; function f(){ return scope; } return f; } checkscope()();
猜猜兩段代碼各自的執(zhí)行結(jié)果是多少?
這里直接告訴大家結(jié)果,兩段代碼都會(huì)打印:local scope。
原因也很簡單,因?yàn)镴avaScript采用的是詞法作用域,函數(shù)的作用域基于函數(shù)創(chuàng)建的位置。
而引用《JavaScript權(quán)威指南》的回答就是:
JavaScript 函數(shù)的執(zhí)行用到了作用域鏈,這個(gè)作用域鏈?zhǔn)窃诤瘮?shù)定義的時(shí)候創(chuàng)建的。嵌套的函數(shù) f() 定義在這個(gè)作用域鏈里,其中的變量 scope 一定是局部變量,不管何時(shí)何地執(zhí)行函數(shù) f(),這種綁定在執(zhí)行 f() 時(shí)依然有效。
但是在這里真正想讓大家思考的是:
雖然兩段代碼執(zhí)行的結(jié)果一樣,但是兩段代碼究竟有哪些不同呢?
如果要回答這個(gè)問題,就要牽涉到很多的內(nèi)容,詞法作用域只是其中的一小部分,讓我們期待下一篇文章————《JavaScript深入之執(zhí)行上下文?!?。
下一篇文章JavaScript深入之執(zhí)行上下文棧
深入系列JavaScript深入系列目錄地址:https://github.com/mqyqingfeng/Blog。
JavaScript深入系列預(yù)計(jì)寫十五篇左右,旨在幫大家捋順JavaScript底層知識(shí),重點(diǎn)講解如原型、作用域、執(zhí)行上下文、變量對(duì)象、this、閉包、按值傳遞、call、apply、bind、new、繼承等難點(diǎn)概念。
如果有錯(cuò)誤或者不嚴(yán)謹(jǐn)?shù)牡胤?,?qǐng)務(wù)必給予指正,十分感謝。如果喜歡或者有所啟發(fā),歡迎star,對(duì)作者也是一種鼓勵(lì)。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/82382.html
摘要:在中的應(yīng)用采用詞法作用域,也就是靜態(tài)作用域。那什么又是詞法作用域或者靜態(tài)作用域呢請(qǐng)繼續(xù)往下看靜態(tài)作用域與動(dòng)態(tài)作用域因?yàn)椴捎玫氖窃~法作用域函數(shù)的作用域在函數(shù)定義的時(shí)候就決定了。 開篇 當(dāng)我們在開始學(xué)習(xí)任何一門語言的時(shí)候,都會(huì)接觸到變量的概念,變量的出現(xiàn)其實(shí)是為了解決一個(gè)問題,為的是存儲(chǔ)某些值,進(jìn)而,存儲(chǔ)某些值的目的是為了在之后對(duì)這個(gè)值進(jìn)行訪問或者修改,正是這種存儲(chǔ)和訪問變量的能力將狀態(tài)給...
摘要:下面,讓我們以一個(gè)函數(shù)的創(chuàng)建和激活兩個(gè)時(shí)期來講解作用域鏈?zhǔn)侨绾蝿?chuàng)建和變化的。這時(shí)候執(zhí)行上下文的作用域鏈,我們命名為至此,作用域鏈創(chuàng)建完畢。 JavaScript深入系列第五篇,講述作用鏈的創(chuàng)建過程,最后結(jié)合著變量對(duì)象,執(zhí)行上下文棧,讓我們一起捋一捋函數(shù)創(chuàng)建和執(zhí)行的過程中到底發(fā)生了什么? 前言 在《JavaScript深入之執(zhí)行上下文?!分兄v到,當(dāng)JavaScript代碼執(zhí)行一段可執(zhí)行代...
摘要:開篇作用域是每種計(jì)算機(jī)語言最重要的基礎(chǔ)之一,因此要想深入的學(xué)習(xí)作用域和作用域鏈就是個(gè)繞不開的話題。這樣由多個(gè)執(zhí)行上下文的變量對(duì)象構(gòu)成的鏈表就叫做作用域鏈。這時(shí)候執(zhí)行上下文的作用域鏈,我們命名為至此,作用域鏈創(chuàng)建完畢。 開篇 作用域是每種計(jì)算機(jī)語言最重要的基礎(chǔ)之一,因此要想深入的學(xué)習(xí)JavaScript,作用域和作用域鏈就是個(gè)繞不開的話題。 在《深入學(xué)習(xí)js之—-執(zhí)行上下文?!分形覀兲岬?..
摘要:函數(shù)作用域和塊作用域前面講了是詞法作用域,那么什么時(shí)候會(huì)創(chuàng)建作用域呢主要是基于函數(shù)級(jí)別的作用域,也就是每一個(gè)函數(shù)都會(huì)創(chuàng)建一個(gè)作用域。函數(shù)會(huì)被當(dāng)作函數(shù)表達(dá)式而不是一個(gè)標(biāo)準(zhǔn)的函數(shù)聲明來處理。 什么是作用域 來一段《你不知道的JavaScript-上卷》中的原話: 幾乎所有編程語言最基本的功能之一,就是能夠儲(chǔ)存變量當(dāng)中的值,并且能在之后對(duì)這個(gè) 值進(jìn)行訪問或修改,這些變量住在哪里?換句話說,它...
摘要:深入系列第七篇,結(jié)合之前所講的四篇文章,以權(quán)威指南的為例,具體講解當(dāng)函數(shù)執(zhí)行的時(shí)候,執(zhí)行上下文棧變量對(duì)象作用域鏈?zhǔn)侨绾巫兓摹G把栽谏钊胫畧?zhí)行上下文棧中講到,當(dāng)代碼執(zhí)行一段可執(zhí)行代碼時(shí),會(huì)創(chuàng)建對(duì)應(yīng)的執(zhí)行上下文。 JavaScript深入系列第七篇,結(jié)合之前所講的四篇文章,以權(quán)威指南的demo為例,具體講解當(dāng)函數(shù)執(zhí)行的時(shí)候,執(zhí)行上下文棧、變量對(duì)象、作用域鏈?zhǔn)侨绾巫兓摹?前言 在《Jav...
閱讀 2856·2023-04-26 01:02
閱讀 1884·2021-11-17 09:38
閱讀 808·2021-09-22 15:54
閱讀 2912·2021-09-22 15:29
閱讀 903·2021-09-22 10:02
閱讀 3456·2019-08-30 15:54
閱讀 2021·2019-08-30 15:44
閱讀 1607·2019-08-26 13:46