久久久久久久视色,久久电影免费精品,中文亚洲欧美乱码在线观看,在线免费播放AV片

<center id="vfaef"><input id="vfaef"><table id="vfaef"></table></input></center>

    <p id="vfaef"><kbd id="vfaef"></kbd></p>

    
    
    <pre id="vfaef"><u id="vfaef"></u></pre>

      <thead id="vfaef"><input id="vfaef"></input></thead>

    1. 站長資訊網(wǎng)
      最全最豐富的資訊網(wǎng)站

      手把手帶你了解Javascript中變量和詞法環(huán)境

      手把手帶你了解Javascript中變量和詞法環(huán)境

      其實,我覺得Javascript核心中重要的東西并非是從舊版本擴(kuò)展來的高大上的語法,例如解構(gòu)賦值啊、展開語法和剩余參數(shù)(嘛……雖然的確是很666),但是用好這些,其實都建立在你對變量的認(rèn)識上(常有人不知道什么是左值或右值的區(qū)別)正因如此,我覺得了解一個Javascript還是從最基本做起,就是了解一下何為變量吧。

      本文其實也并非完全基礎(chǔ),還是建立在對Javascript有一定了解之上的,至少對對象要有一定的認(rèn)知。開始吧。

      變量與數(shù)據(jù)

      什么是變量?

      越簡單的問題答案往往越是讓人感到意外,多數(shù)人的答案都與有關(guān);事實上變量就是程序可操作的存儲區(qū)(術(shù)語內(nèi)存空間),在Javascript程序運行時,存儲區(qū)(術(shù)語就是內(nèi)存空間)可以保存我們所需的任何東西,代碼、數(shù)據(jù)……等等。然后可以將變量保存的數(shù)據(jù)大致上分割為兩類:原始類型(同基本類型)和引用類型;從變量中取出來的數(shù)據(jù)就是值,把一個值放到變量中時,該值就又變成了數(shù)據(jù)。

      Javascript和其他語言相似,變量也需要被聲明才能實際存在,聲明后的變量稱之為實例化,為變量賦予一個值(默認(rèn)為undefined)時,稱之為變量的初始化,只是實例化而未初始化的變量都處于uninitialized狀態(tài)。

      例如:

      let a = a ;         // (*) console.log(a); // ReferenceError: can't access lexical declaration `a' before initialization

      很完美的報錯了(在(*)標(biāo)志的位置),提示我們沒有初始化這個變量時就無法使用。這是不同于C++這類底層的變量的地方。其實這種現(xiàn)象在Javascript有一個極為高大上的名字:暫存死區(qū),等過幾章節(jié)我就說明產(chǎn)生的原因。

      (忘了說了,在變量聲明也需要一個名字,術(shù)語稱作標(biāo)識符,我覺得不補(bǔ)充也不影響什么……)

      不過Javascript另外特殊的地方在于,它對var聲明的變量是可以自動初始化的,Javascript會自動會為var聲明的變量賦予一個undefined值。
      例如:

      var a = a;console.log(a);    // undefined.

      看吧,明明都差不多,結(jié)果卻全然不同。
      但是實際上卻沒什么卵用,見下面的代碼:

      var a = a;console.log(a+2);   // NaN

      結(jié)果是NaN, 得到了一個我們完全不想要的結(jié)果。在如果無法順利數(shù)學(xué)計算時,Javascript便會給出一個非數(shù)字的結(jié)果,用NaN表示。但是比較有趣的是,如果你用typeof去驗證NaN類型:

      typeof NaN ;      // number

      卻告訴我們,這TMD是一個數(shù)值 number。
      Javascript莫名其妙的地方還有許多許多,不過我們還是不要繼續(xù)調(diào)戲javascript了,開始認(rèn)真學(xué)習(xí)了。

      類型與存儲

      Javascript一共有 7 種原始類型 和 1 種 引用類型,如下:

      • 原始類型

        1、number

        2、string

        3、boolean

        4、symbol

        5、bigint

        6、undefined

        7、null

      • 引用類型:

        object

      (這里面我就用小寫了,因為typeof返回的是小寫的)
      我就是介紹一下這些必須要了解的東西,具體用法其他資料都有我就不贅述了。不過關(guān)于typeof還有要補(bǔ)充的一點是,它對于nullfunction結(jié)果:

      function sayHello(){      console.log('hello the world');  }  console.log(typeof sayHello);  // function  console.log(typeof null);      // object

      ……對于一個函數(shù),它真的返回的是一個“函數(shù)”,某種意義上用處很大,不過對null值返回一個object,這只能說有得就有缺吧。

      我覺得對變量加深了解的辦法就是明白它的底層運作方式。其實也沒有什么了不起的,原始值是直接放在內(nèi)存棧區(qū), 引用類型值則是放在內(nèi)存堆區(qū)(這是它的實際存儲區(qū)位置);(如果是常量,那么就會放在中,好像也是棧區(qū)的一部分)。正常情況下,變量取值都是直接都是從內(nèi)存棧區(qū)中獲取的,但是引用類型的值是放在內(nèi)存堆中,那么怎么辦?

      引用類型值的訪問:

      1、一個引用類型的變量,會在內(nèi)存棧中保存一個指針

      2、這個指針是用于引用內(nèi)存堆中的存儲區(qū)的內(nèi)存地址

      3、在訪問一個類型值時

      4、會通過指針找到內(nèi)存堆中的存儲區(qū),然后從中獲取值。

      例如:

        var first  = {       name:'hahei...'   }   var gggiii=111222;

      映射圖如下:

      手把手帶你了解Javascript中變量和詞法環(huán)境

      注意:此處我用 ref. first表示 存儲區(qū)的引用 , 因為雖然保存的盡管是指針,但是在訪問這個值時,會進(jìn)行二次解析(即通過這個指針找到存儲區(qū)), 而不是直接返回這個指針的具體數(shù)據(jù)。詳細(xì)可以參考 C++引用。

      初識詞法環(huán)境

      想必各位都已經(jīng)對什么是作用域了若指掌,但是我還是必須重新提一下作用域標(biāo)識符的可訪問范圍,在Javascript中的任何操作,幾乎都有作用域的參與。Javascript中使用詞法環(huán)境決定作用域,在下面我會簡單介紹一下。(請注意,這里我沒有用變量這個術(shù)語,因為解析標(biāo)識符范圍時,應(yīng)該還沒有真正生成代碼,感興趣的可以去了解一下AST語法樹

      看,以下代碼:

       var val=111;  function hahaha(){      console.log(val);  }  function hihihi(){     hahaha();  }  hihihi();  /// 111

      的確是正確輸出了,111。

      但是我更喜歡把 val放在一個函數(shù)中,如:

         function hahaha(){        console.log(val);      /// (**)    }    function hihihi(){       var val=111;            /// (*)       hahaha();    }    hihihi();

      結(jié)果就是Uncaught ReferenceError: val is not defined, 根本沒找到val這個標(biāo)識符,這是為什么?

      因為執(zhí)行過程是這樣的:

      1. hihihi函數(shù)執(zhí)行 , 然后為 val賦值……
      2. hahaha函數(shù)執(zhí)行
      3. hahaha找不到val標(biāo)識符,便去外部詞法環(huán)境
      4. hahaha外部詞法環(huán)境就是** hahaha函數(shù)聲明時代碼的外部**,即全局代碼(下稱全局詞法環(huán)境)
      5. 全局詞法環(huán)境沒找到val,終了。
        (請注意3-5步, 找val找的是函數(shù)聲明代碼的外部,而不是函數(shù)調(diào)用時的位置。)

      現(xiàn)在應(yīng)該提一下概念了,詞法環(huán)境(Lexical Environment)就是根據(jù)代碼結(jié)構(gòu)時決定的作用域,也可以稱作詞法作用域(Lexical Scoping)它是靜態(tài)作用域??梢赃@么說,在源代碼寫好時,所有標(biāo)識符的作用域就已經(jīng)被決定。當(dāng)然也有動態(tài)作用域,你可以去試試bash腳本,它就是動態(tài)的。嘿嘿。詳細(xì)也可以參考靜態(tài)作用域、詞法作用域。

      此處只要發(fā)現(xiàn)了個中區(qū)別就極好掌握,所以我就略了。

      詞法環(huán)境的抽象

      在Javascript常用三種詞法環(huán)境: 一、塊級作用域 二、全局作用域 三、函數(shù)作用域。

      有時,我們會將一個詞法環(huán)境(即作用域,下面我會正式使用詞法環(huán)境替代作用域這個術(shù)語)抽象成偽代碼,如下:

      	LexicalEnvironment = { 		OuterEnv: < ... > , 		This :   < ... > , 		EnvironmentRecord:{ 			// ... identifiername:variable 		} 	}

      很簡單:

      • OuterEnv:當(dāng)前詞法環(huán)境的外部詞法環(huán)境
      • This: 當(dāng)前詞法環(huán)境的 this的值,但它是運行時決定的。
      • EnvironmentRecord(環(huán)境記錄): 標(biāo)識符-變量的映射,注意,這里的標(biāo)識符只是單純的字符串,變量指的是存儲區(qū)的數(shù)據(jù)。而且標(biāo)識符必須是當(dāng)前詞法環(huán)境,而不是當(dāng)前代碼的。

      例如:

        function first(){       var a  =100;       let d = 220;       {     // Block,            var b = a+100;           let c = b*10;           console.log(a,b,c,d);       }   }   first();  // 100 200 2000 220

      一定不要忽略first函數(shù)中的塊級作用域,這很重要。

      然后寫成抽象就是:
      函數(shù)內(nèi)部的塊級作用域

      	BlockEnv = { 		OuterEnv: < FuncFirstEnv > , 		This :   < window > , 		EnvironmentRecord:{ 			c:< 2000 >              // 這里沒有b 		} 	}

      函數(shù)作用域

      	FuncEnv = { 		OuterEnv: < GlobalEnv > , 		This :   < window > , 		EnvRec:{ 			a:< 100 >, 			d:< 220 >, 			b:< 200 > 		} 	}

      OKay,先到這里吧。

      一些問題:

      1、為什么用詞法環(huán)境代替作用域?
      –詞法環(huán)境涵蓋了作用域,但反之則不能。
      –但注意,詞法作用域和詞法作用域鏈與作用域以及作用域鏈都可通用。

      2、環(huán)境記錄是什么?
      –當(dāng)前環(huán)境下的標(biāo)識符-變量的映射
      –但是標(biāo)識符只是“合法標(biāo)識符”的字符串形式。
      –變量是是指存儲區(qū)的內(nèi)容,但是確切說法是存儲區(qū)。

      最后

      我把我的筆記,重新整理后發(fā)到博客上后發(fā)現(xiàn)——我筆記干凈了好多,艸。

      這種只深入核心的內(nèi)容很有用,而且在寫代碼時也變得靈活很多了。我覺得這就是最有用的地方
      最后:
      個人理解,常有失誤;細(xì)細(xì)查看不知何處,望君做到心中有數(shù)。

      本文轉(zhuǎn)載自:https://blog.csdn.net/krfwill/article/details/106155266

      相關(guān)教程推薦:JavaScript視頻教程

      贊(0)
      分享到: 更多 (0)
      網(wǎng)站地圖   滬ICP備18035694號-2    滬公網(wǎng)安備31011702889846號