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

資訊專欄INFORMATION COLUMN

JavaScript之變量及作用域

Faremax / 2599人閱讀

摘要:所以的作用域是靜態(tài)作用域,也叫詞法作用域。總結(jié)是一門基于詞法作用域靜態(tài)作用域的語言,會沿著作用域鏈像氣泡一樣向外部尋找變量聲明。又是函數(shù)作用域的語言,在中,使用和關(guān)鍵字后,能讓變量處于塊作用域中,而且不存在聲明提升。

本文共 1700 字,讀完只需 7 分鐘
概述

變量,編程語言中我們用來模擬現(xiàn)實(shí)概念的工具,比方說,變量可以表示對象,數(shù)組,數(shù)字,字符。既然是工具,那么就用工具的適用范圍,這個工具在這個適用范圍中才有效,在編程語言中,我們稱這個適用范圍叫作用域(scope)

本文會總結(jié) JS 中作用域的相關(guān)概念。

什么是作用域

全局作用域

函數(shù)作用域

塊級作用域

詞法作用域(靜態(tài)作用域)

作用域鏈

一、什么是作用域?

作用域, 英文意思是 scope, 我自己的話來理解就是:

變量訪問規(guī)則的有效范圍

作用域外,無法引用作用域內(nèi)的變量

離開作用域后,作用域的變量的內(nèi)存空間會被清除,比如執(zhí)行完函數(shù)或者關(guān)閉瀏覽器。

二、全局作用域

先看一段代碼:

foo = "bar";
console.log(window.foo);  // bar

在瀏覽器環(huán)境中聲明變量,該變量會默認(rèn)成為全局 windows 對象的屬性。

再看下面這段代碼:

function foo() {
    name = "bar"
}
foo();
console.log(window.name) // bar

在函數(shù)中,如果不加 bar聲明一個變量,那么這個變量會默認(rèn)被聲明為全局變量,如果是嚴(yán)格模式則會報錯。

全局變量可以在任何地方訪問到,但是有很大的問題存在。

全局變量會造成命名污染,如果在多處對同一個全局變量進(jìn)行操作,那么就會覆蓋全局變量的定義。同時全局變量數(shù)量過多,非常不方便管理。

這也是為什么像jQuery 和 underscore 這樣的類庫,要在全局建立 $ 和 _ 變量,其余私有方法屬性掛載到該全局變量下。

三、函數(shù)作用域

JS 是函數(shù)作用域,在函數(shù)中定義一個局部變量,那么該變量只可以在該函數(shù)作用域中被訪問。

function doSomething() {
    var thing = "吃早餐";
}

console.log(thing);  // Uncaught ReferenceError: thing is not defined

嵌套函數(shù)作用域:

function outter() {
    var thing = "吃早餐";
    function inner() {
        console.log(thing);
    }
    inner();
}

outter();  // 吃早餐

在外層函數(shù)中,嵌套一個內(nèi)層函數(shù),那么這個內(nèi)層函數(shù)可以向上訪問到外部作用域的變量。

那么,既然內(nèi)層函數(shù)可以訪問到外層函數(shù)的變量,那么把內(nèi)層函數(shù)返回后呢?

function outter() {
    var thing = "吃晚餐";
    
    function inner() {
        console.log(thing);
    }
    return inner;
}

var foo = outter();
foo();  // 吃晚餐

前面我們提到了,函數(shù)執(zhí)行完后,函數(shù)作用域的變量會被垃圾回收,以上代碼可以看出當(dāng)我們返回了一個訪問了外部函數(shù)變量的內(nèi)部函數(shù),最后外部函數(shù)的變量得以保存。

這種當(dāng)變量存在的函數(shù)已經(jīng)執(zhí)行結(jié)束,但仍在可以訪問的方式就是`閉包`。

閉包的具體實(shí)踐,后續(xù)文章會詳細(xì)說明。
四、塊級作用域

JS 在 ES6 之前只有函數(shù)作用域,沒有塊級作用域的概念。
看一下代碼:

function doSomething() {
    for (var i = 0; i < 10; i++) {
        ...
    }
    console.log(i)
}
doSomething();  // 10

由于 JS 沒有塊級作用域,變量 i 在函數(shù)作用域中只有一個,每次 for 循壞都在改變這一個變量。

再看阮一峰老師 ES6 教程里的一段代碼:

var a = [];
for (var i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6]();   // 10;

以上代碼中,由于沒有塊級作用域,i 變量全局只有一個,當(dāng) for 循壞結(jié)束,變量 i 的值等于 10, 所以 a[6]() 對應(yīng)函數(shù)內(nèi)的變量 i 的打印值就是 10。

ES 6 中通過 letconst關(guān)鍵字 引用了塊級作用域的概念,所謂塊級作用域,就是以 {}包裹的區(qū)域。

我們將阮一峰老師 ES6 教程里的一段代碼改成 let 的形式:

var a = [];
for (let i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6]();   // 6;

這時,數(shù)組內(nèi)的索引為6函數(shù)內(nèi)的變量打印值為6,每次循環(huán),會創(chuàng)建新的塊級作用域,然后重新聲明一個新的變量 i;JS 的解釋引擎會記住上次循環(huán)的變量值,所以能夠返回正確的結(jié)果。

letconst 會聲明一個塊級作用域的變量及常量,不易發(fā)生變量命名污染的問題,能規(guī)避沖突,幫助你寫出簡潔優(yōu)雅的代碼,建議一直使用。

五、詞法作用域(靜態(tài)作用域)

詞法作用域,也可以叫做靜態(tài)作用域,是什么意思呢?

無論函數(shù)在哪里調(diào)用,詞法作用域都只由函數(shù)被聲明時所處的位置決定。

既然有靜態(tài)作用域,那么也有動態(tài)作用域。

而動態(tài)作用域的作用域則是由函數(shù)被調(diào)用執(zhí)行的位置所決定。

var a = 123;

function func1() {
    console.log(a);
}

function func2() {
    var a = 456;
    func1();
}

func2(); // 123

以上代碼,最后輸出結(jié)果 a 的值,來自于 func1 聲明時所在位置訪問到的 a 值 123。

所以 JS 的作用域是靜態(tài)作用域,也叫詞法作用域。

六、作用域鏈

在 JS 引擎中,通過標(biāo)識符查找標(biāo)識符的值,會從當(dāng)前作用域向上尋找,直到作用域找到第一個匹配的標(biāo)識符為止。就是 JS 的作用域鏈

如果嵌套作用域有多個相同標(biāo)識符,那么,最內(nèi)部的標(biāo)識符會覆蓋外層標(biāo)識符,這叫做“遮蔽效應(yīng)”

var a = 1;
function func1() {
    var a = 2;
    function func2() {
        var a = 3;
        console.log(a);  // 3
    }
    func2();
}

func1(); // 3

func2 中變量 a,會從內(nèi)部開始向外部上層尋找,找到最近的 a 標(biāo)識符的聲明為止。

總結(jié)

JS 是一門基于詞法作用域(靜態(tài)作用域)的語言,JS 會沿著作用域鏈像氣泡一樣向外部尋找變量聲明。

JS 又是函數(shù)作用域的語言,在 ES6 中,使用 letconst 關(guān)鍵字后,能讓變量處于塊作用域中,而且不存在聲明提升。

后面的文章會介紹 JS 中的聲明提升和閉包,敬請期待。

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

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

相關(guān)文章

  • javascript作用和閉包我見

    摘要:查詢是在作用域鏈中,一級級的往上查找該變量的引用。作用域和作用域鏈作用域的概念,應(yīng)該兩張圖幾句話就能解釋吧。這個建筑代表程序中的嵌套作用域鏈。一層嵌一層的作用域形成了作用域鏈,變量在作用域鏈中的函數(shù)內(nèi)得到了自己的定義。 javascript作用域和閉包之我見 看了《你不知道的JavaScript(上卷)》的第一部分——作用域和閉包,感受頗深,遂寫一篇讀書筆記加深印象。路過的大牛歡迎指點(diǎn)...

    SoapEye 評論0 收藏0
  • JS編譯 LHS RHS(你不知道的JavaScript 小記一)

    摘要:關(guān)于兩個專業(yè)術(shù)語的討論起自對你不知道的一書的閱讀學(xué)習(xí)。遇到,編譯器會詢問作用域是否已經(jīng)有一個該名稱的變量存在于同一個作用域的集合中。摘錄來自你不知道的。 JS 編譯之 LHS RHS 一、前言 最近和朋友聊技術(shù)的時候,聊到 LHS RHS,我竟然沒聽說過 沒聽說過。。。 于是成功引起了我的好奇心。 關(guān)于兩個專業(yè)術(shù)語的討論起自對《你不知道的JavaScript》一書的閱讀學(xué)習(xí)。 二、編譯...

    Cristic 評論0 收藏0
  • JavaScript 闖關(guān)記

    摘要:對象數(shù)組初始化表達(dá)式,闖關(guān)記之上文檔對象模型是針對和文檔的一個。闖關(guān)記之?dāng)?shù)組數(shù)組是值的有序集合。數(shù)組是動態(tài)的,根闖關(guān)記之語法的語法大量借鑒了及其他類語言如和的語法。 《JavaScript 闖關(guān)記》之 DOM(下) Element 類型 除了 Document 類型之外,Element 類型就要算是 Web 編程中最常用的類型了。Element 類型用于表現(xiàn) XML 或 HTML 元素...

    mj 評論0 收藏0
  • 前端面試閉包

    摘要:在函數(shù)內(nèi)部的變量稱之為局部變量,它可以在函數(shù)內(nèi)部讀取,在函數(shù)外部無法正常讀取,如果想要讀取函數(shù)內(nèi)部的變量則需要用到閉包。 前端面試之閉包 閉包屬于屬于JavaScript的難點(diǎn),但是在很多高級應(yīng)用都需要用到,也是前端面試中經(jīng)常會考到的點(diǎn)。 作用域 談到閉包首先必須了解作用域,ES5中,JavaScript的作用域只有兩種,一種是全局作用域,變量在整個程序中一直存在,所有地方都可以讀取;...

    jackzou 評論0 收藏0
  • Javascript重溫OOP作用與閉包

    摘要:的變量作用域是基于其特有的作用域鏈的。需要注意的是,用創(chuàng)建的函數(shù),其作用域指向全局作用域。所以,有另一種說法認(rèn)為閉包是由函數(shù)和與其相關(guān)的引用環(huán)境組合而成的實(shí)體。 作用域 定義 在編程語言中,作用域控制著變量與參數(shù)的可見性及生命周期,它能減少名稱沖突,而且提供了自動內(nèi)存管理 --javascript 語言精粹 我理解的是,一個變量、函數(shù)或者成員可以在代碼中訪問到的范圍。 js的變量作...

    JessYanCoding 評論0 收藏0

發(fā)表評論

0條評論

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