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

資訊專欄INFORMATION COLUMN

深入學習js之——詞法作用域和動態(tài)作用域

shiweifu / 2218人閱讀

摘要:在中的應用采用詞法作用域,也就是靜態(tài)作用域。那什么又是詞法作用域或者靜態(tài)作用域呢請繼續(xù)往下看靜態(tài)作用域與動態(tài)作用域因為采用的是詞法作用域函數(shù)的作用域在函數(shù)定義的時候就決定了。

開篇

當我們在開始學習任何一門語言的時候,都會接觸到變量的概念,變量的出現(xiàn)其實是為了解決一個問題,為的是存儲某些值,進而,存儲某些值的目的是為了在之后對這個值進行訪問或者修改,正是這種存儲和訪問變量的能力將狀態(tài)給了程序。我們的程序中到處都充斥著對于狀態(tài)的判斷,根據(jù)不同的狀態(tài)執(zhí)行不同的邏輯。

我們試想一下,如果沒有狀態(tài)這個概念,程序雖然也能夠執(zhí)行一些簡單的任務,但是它會受到很多的限制,所能完成的功能是有限制的,舉個例子,沒有狀態(tài)你是如何執(zhí)行循環(huán)語句?沒有狀態(tài)如何更加優(yōu)雅地使用邏輯結(jié)構(gòu)

仔細想想,好像是寸步難行,當然引入變量后幫我們解決了這個問題。

但是,引入變量和狀態(tài)的概念之后會引起幾個問題:這些變量住在哪里?換句話說,它們存儲在哪里?最重要的是,程序需要它們的時候如何找到它們?

今天我們就一起學習一下這套存儲和查找變量的規(guī)則,這套規(guī)則我們稱之為:作用域。

作用域

我們來拆解一下這個詞語,所謂的“”我們可以理解為:范圍、區(qū)域,加上“作用”兩個字所要表述的問題就是作用的范圍、區(qū)域,比如國家的行政區(qū)域劃分是為了便于管理,類比到程序源代碼中作用域的出現(xiàn)也是為了便于對于變量做管理。

好,這里我們簡單做一下總結(jié):

定義:作用域是指程序源代碼中定義變量的區(qū)域。

作用:作用域規(guī)定了如何查找變量,也就是確定當前執(zhí)行代碼對變量的訪問權(quán)限。

在javaScript中的應用 :JavaScript采用詞法作用域(lexical scoping),也就是靜態(tài)作用域

那什么又是 詞法作用域或者靜態(tài)作用域呢?

請繼續(xù)往下看

靜態(tài)作用域與動態(tài)作用域

因為javaScript采用的是詞法作用域,函數(shù)的作用域在函數(shù)定義的時候就決定了。
而詞法作用域相對的是動態(tài)作用域,函數(shù)的作用域是在函數(shù)調(diào)用的時候才決定的。
讓我們看一個例子來理解詞法作用域和動態(tài)作用域之間的區(qū)別:

var value = 1;

function foo() {
  console.log(value);
}

function bar() {
  var value = 2;
  foo();
}

bar();
// 結(jié)果是 ???

上面的代碼中:

1.我們首先定義了一個value,并賦值為1;

2.聲明一個函數(shù)foo,函數(shù)的功能是打印 value 這個變量的值;

3.聲明一個函數(shù)bar,函數(shù)內(nèi)部重新創(chuàng)建了一個變量 value 這個變量賦值為2;
在函數(shù)內(nèi)部執(zhí)行了 foo() 這個函數(shù);

4.執(zhí)行 bar() 這個函數(shù)

假設(shè)javaScript采用靜態(tài)作用域,讓我們分析下執(zhí)行過程:

執(zhí)行foo函數(shù),首先從 foo 函數(shù)內(nèi)部查找是否有變量 value ,如果沒有
就根據(jù)書寫的位置,查找上面一層的代碼,我們發(fā)現(xiàn)value等于1,所以結(jié)果會打印 1。

假設(shè)javaScript采用動態(tài)作用域,讓我們分析下執(zhí)行過程:

執(zhí)行foo函數(shù),依然是從 foo 函數(shù)內(nèi)部查找是否有局部變量 value。如果沒有,
就從調(diào)用函數(shù)的作用域,也就是 bar 函數(shù)內(nèi)部查找 value 變量,所以結(jié)果會打印 2。

上面在區(qū)分靜態(tài)作用于和動態(tài)作用域的時候,我們已經(jīng)說了如果是靜態(tài)作用域,那么函數(shù)在書寫定義的時候已經(jīng)確定了,而動態(tài)作用域是函數(shù)執(zhí)行過程中才確定的。

JavaScript采用的是靜態(tài)作用域,所以這個例子的結(jié)果是 1。
我們在控制臺中輸入執(zhí)行上面的函數(shù),檢驗一下執(zhí)行結(jié)果果然是 1。

動態(tài)作用域

那什么語言是采用的動態(tài)的作用域呢? 其實bash 就是動態(tài)作用域,
我們可以新建一個 scope.bash 文件將下列代碼放進去,執(zhí)行一下這個腳本文件:

#!/bin/bash

value=1
function foo () {
    echo $value;
}
function bar () {
  local value=2;
  foo;
}
bar

上面代碼運行的結(jié)果輸出2很好解釋,雖然在代碼最上層定義了 value并賦值為1,但是在調(diào)用foo函數(shù)的時候,在查找 foo 內(nèi)部沒有 value 變量后,會在foo 函數(shù)執(zhí)行的環(huán)境中繼續(xù)查找,也就是在bar 函數(shù)中查找,很幸運我們找到了。

思考

最后,讓我們看一個《JavaScript權(quán)威指南》中的例子:

// 例1:
var scope = "global scope";
function checkscope(){
  var scope = "local scope";
  function f(){
    return scope;
  }
  return f();
}
checkscope();

// 例2:
var scope = "global scope";
function checkscope(){
  var scope = "local scope";
  function f(){
    return scope;
  }
  return f;
}
checkscope()();

讓我們來分析一下上面例1的代碼:

1、定義一個變量 scope 并賦值 global scope;

2、聲明一個函數(shù) checkscope ,在這個函數(shù)中 定義一個變量 scope 并賦值 local scope;

3、在checkscope 函數(shù)中 又定義一個函數(shù) f ,這個函數(shù) 只做了一件事:返回scope 這個變量;

4、最后返回并執(zhí)行 f 這個函數(shù);

5、調(diào)用checkscope

按照我們上面解釋的javaScript中靜態(tài)作用域理解,在執(zhí)行 checkscope 這個函數(shù)的時候在函數(shù)內(nèi)部執(zhí)行的是f 這個函數(shù),首先在 f 這個函數(shù)內(nèi)部查找 scope 這個變量發(fā)現(xiàn)沒有,繼續(xù)在定義函數(shù)f的上面一層查找,發(fā)現(xiàn)在checkscope 這個函數(shù)作用域內(nèi) 找到了scope的值 直接返回,至于 checkscope外面定義的scope沒有理睬。

讓我們來分析一下上面例2的代碼:

1、定義一個變量 scope 并賦值 global scope;

2、聲明一個函數(shù) checkscope 在這個函數(shù)中 定義一個變量 scope 并賦值 local scope;

3、在checkscope 函數(shù)中 又定義一個函數(shù) f 這個函數(shù) 只做了一件事:返回scope 這個變量;

4、最后單純的返回 f 這個函數(shù);

5、調(diào)用checkscope

按照我們上面解釋的javaScript中靜態(tài)作用域理解,在執(zhí)行 checkscope 這個函數(shù)的時候在函數(shù)內(nèi)返回了函數(shù)f實際是在最外面調(diào)用的f但是由于javaScript是采用的詞法作用域,因此函數(shù)的作用域基于函數(shù)創(chuàng)建的位置。

而引用《JavaScript權(quán)威指南》的回答就是:

JavaScript 函數(shù)的執(zhí)行用到了作用域鏈,這個作用域鏈是在函數(shù)定義的時候創(chuàng)建的。嵌套的函數(shù) f() 定義在這個作用域鏈里,其中的變量 scope 一定是局部變量,不管何時何地執(zhí)行函數(shù) f(),這種綁定在執(zhí)行 f() 時依然有效。

但是在這里真正想讓大家思考的是:

雖然兩段代碼執(zhí)行的結(jié)果一樣,但是兩段代碼究竟有哪些不同呢?

敬請期待下面一篇關(guān)于javaScript 中的執(zhí)行上下文棧的相關(guān)內(nèi)容。

參考:

1、《你不知道的Javascript上卷》

2、JavaScript深入之詞法作用域和動態(tài)作用域

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

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/101512.html

相關(guān)文章

  • JavaScript深入詞法作用動態(tài)作用

    摘要:作用域作用域是指程序源代碼中定義變量的區(qū)域。采用詞法作用域,也就是靜態(tài)作用域。而與詞法作用域相對的是動態(tài)作用域,函數(shù)的作用域是在函數(shù)調(diào)用的時候才決定的。前面我們已經(jīng)說了,采用的是靜態(tài)作用域,所以這個例子的結(jié)果是。 JavaScript深入系列的第二篇,JavaScript采用詞法作用域,什么語言采用了動態(tài)作用域?兩者的區(qū)別又是什么?還有一個略難的思考題,快來看看吧。 作用域 作用域是指...

    gclove 評論0 收藏0
  • 深入學習js——作用

    摘要:開篇作用域是每種計算機語言最重要的基礎(chǔ)之一,因此要想深入的學習作用域和作用域鏈就是個繞不開的話題。這樣由多個執(zhí)行上下文的變量對象構(gòu)成的鏈表就叫做作用域鏈。這時候執(zhí)行上下文的作用域鏈,我們命名為至此,作用域鏈創(chuàng)建完畢。 開篇 作用域是每種計算機語言最重要的基礎(chǔ)之一,因此要想深入的學習JavaScript,作用域和作用域鏈就是個繞不開的話題。 在《深入學習js之—-執(zhí)行上下文棧》中我們提到...

    lemanli 評論0 收藏0
  • 【前端工程師手冊】JavaScript作用

    摘要:函數(shù)作用域和塊作用域前面講了是詞法作用域,那么什么時候會創(chuàng)建作用域呢主要是基于函數(shù)級別的作用域,也就是每一個函數(shù)都會創(chuàng)建一個作用域。函數(shù)會被當作函數(shù)表達式而不是一個標準的函數(shù)聲明來處理。 什么是作用域 來一段《你不知道的JavaScript-上卷》中的原話: 幾乎所有編程語言最基本的功能之一,就是能夠儲存變量當中的值,并且能在之后對這個 值進行訪問或修改,這些變量住在哪里?換句話說,它...

    Paul_King 評論0 收藏0
  • JavaScript深入作用

    摘要:下面,讓我們以一個函數(shù)的創(chuàng)建和激活兩個時期來講解作用域鏈是如何創(chuàng)建和變化的。這時候執(zhí)行上下文的作用域鏈,我們命名為至此,作用域鏈創(chuàng)建完畢。 JavaScript深入系列第五篇,講述作用鏈的創(chuàng)建過程,最后結(jié)合著變量對象,執(zhí)行上下文棧,讓我們一起捋一捋函數(shù)創(chuàng)建和執(zhí)行的過程中到底發(fā)生了什么? 前言 在《JavaScript深入之執(zhí)行上下文棧》中講到,當JavaScript代碼執(zhí)行一段可執(zhí)行代...

    waltr 評論0 收藏0
  • javascript中關(guān)于作用閉包

    摘要:在代碼執(zhí)行時,對應的作用域鏈常常是保持靜態(tài)的。當語句執(zhí)行完畢后,會把作用域鏈恢復到原始狀態(tài)。在全局作用域中創(chuàng)建的函數(shù),其作用域鏈會自動成為全局作用域中的一員。 列表項目 前言 學習了javascript已經(jīng)很久了,關(guān)于這個語言中的這兩個特性也是早已耳熟能詳,但是在實際的使用的過程中或者是遇到相關(guān)的問題的時候,還是不能很好的解決。因此我覺得很有必要深入的學習并且記錄這個問題,以便在今后的...

    zacklee 評論0 收藏0

發(fā)表評論

0條評論

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