今天看了前端網上關於JS的題目,其中有一道題目挺有意思的。如下
1 var a = b =10; 2 (function(){ 3 var a = b = 20; 4 })(); 5 console.log(a); 6 console.log(b); 7 問:輸出的 a = ? b = ?
你們想到的結果是什么?
也許絕大多數人和我一樣認為是20、20 。然而答案是10、20,別急我們先來慢慢分析(*^__^*) 嘻嘻……,
1.首先第一行的 var a = b = 10; 就是用了連等操作符,連等操作符是從右向左的 所以類似於b = 10; a = b;或者是 a = (b = 10);這樣的順序進行從右向左的賦值的。
變量a是用var進行聲明並賦值的所以是局部變量,但是b是未聲明而直接進行賦值的所以是全局變量。所以使用連等操作符的時候要不會出現全局變量要不就是使用作用域鏈后端的變量。
2.從第二行開始使用匿名函數實現模仿塊級作用於(私有作用域):在里面聲明的變量會在函數結束后被銷毀除非被外部所使用。第三行進行連等操作,先使用外部局部變量b,b =20; 然后又重新聲明了一個變量a
這是一個跨級作用域重新聲明的a和外部沒有任何一點關系,你可以把它看成任何其它變量不如說var x;
|
然后 var a = b;初始化后的 a為20.
3.第四行聲明定義一個匿名函數后隨即執行,私有作用域中創建的變量a在結束后隨即被銷毀.所以最后改變的只有外部的變量b的值.
趁熱打鐵,我們再來看一道類似的連等操作賦值問題. 如下
1 想想結果是多少吧? 2 var a = {n:1}; 3 var b = a; 4 a.x = a = {n:2}; 5 問:console.log(a.x); 6 console.log(b.x);
也許有的人看到答案又疑惑的,看了上面的感覺自己掌握了,然后這道題卻有出乎意料之外(⊙﹏⊙)b;
結果是
,不知道有沒有小伙伴答對呢.......
讓我們再來分析一下
1.首先第二行聲明並且使用對象字面量語法創建了一個對象,有屬性n = 1;第三行聲明變量b,並且把a的對象引用賦值給b。所以現在變量b和a指向的是同一個對象,即他們現在共享。
2.第四行問題來了,a.x = a = {n:2}; 先創建一個對象{n:2}並把他的引用送給變量a。因為a.x在執行前保留了對{n:1}的引用,所以給原對象增加一個屬性a即對{n:2}的引用
而a現在為{n:2}並沒有x的屬性所以為undefined,而仍然指向原來的引用所以b.x = a;
b.x == a //true
也許講的有點不太清楚,希望你們能說出你們的觀點,也希望自己能對JS理解更深刻
