每日挑戰,從Javascript面試題目了解一些你可能忽略的概念 – Day2

tags: ItIron2021 Javascript

前言

昨天我們透過了一個相當經典的題目探討了基本的作用域(scope)與變數賦值的概念,讓我們沿續這兩個概念繼續進行另一個題目的練習吧! 由於只是概念的應用複習,今天的篇幅甚至會再更短一些! 一起放輕鬆來學習吧!

本日題目與解釋

請問下方的程式碼會有什麼輸出結果?

(function(){
  var a = b = 3
})();

console.log("a defined? " + (typeof a !== 'undefined'));
console.log("b defined? " + (typeof b !== 'undefined'));

這個題目也算相對常見的基本題型之一,當時是在一間博奕公司給的現場測驗中遇到這題目,好在之前自己練習時就有遇到類似的情境才不至於翻車😂

先防雷,來張思考圖片擋一下,思考結束後再往下滑吧!

jerry-think

最終的輸出結果如下

a defined? false
b defined? true

最終a是個未定義的變數,但b則是一個已經定義的變數,且其值為3,那為什麼會有這樣的結果呢? 我們一個個重點來看吧!

  • var a = b = 3 與你想像的執行結果並不相同

很多人會以為下面兩種寫法是完全等價的

var a = b = 3

-----我是分隔線-----
var a = 3
var b = 3

但事實上由於運算子相依性(associativity,也有人說運算子結合率),上方的程式碼賦值部份會是右 -> 左進行,也就是說實際上會是這樣的

b = 3
var a = b

但這樣又有什麼差別呢? 關鍵在於b變成一個類似全域變數的存在,會掛在當下指向的global object下,以瀏覽器為例便是在window物件下
global variable

而var宣告的變數我們在昨天提過,它是functional scoped,也就是說a這個變數僅存在於該立即執行函數(IIFE)中,離開那個函數便無法被使用,最終自然變成not defined的變數囉!

也因此你在很多很多的教材中都會看到永遠都要用var、const/let來宣告變數,以免造成這樣意料之外的行為,現在許多的框架都會自動套用strict mode,在嚴格模式下就會預先替你把這樣的錯誤抓出來囉!
use strict

順帶一提,一次賦值多個變數的寫法是這樣的,利用這樣的寫法修改題目後就會看到我們預期的結果囉!

global variable2

本日核心觀念與總結

核心觀念

scope、變數宣告與賦值、運算子相依性

總結

  1. 永遠都要使用關鍵字宣告變數,以免造成預期外的結果,現在的框架基本上都會幫你做把關
  2. 一次賦值多個變數的寫法並不是var a = b = c,而是需要寫var a = 3, b = 3
  3. 賦值運算子為右相依性,從右判斷到左

發表留言