JavaScript 考題 1

Meow Meow Picture

目錄


作用域、提升

Hoisting

  1. 函式陳述式優先
  2. var 變數

測驗:請問結果為?

var a = 0;
function a() {};
a();
  1. 0
  2. undefined
  3. error

解答:

// 創造
function a() {};
var a;

// 執行
a = 0; // 這步驟就會把 函式 給覆蓋掉
a(); // 這裡其實是 a = 0

測驗:請問結果為?

function b() {
console.log(a);
function a() {};
var a = 3;
}
b();
  1. f() {}
  2. undefined
  3. 3

測驗:請問結果為?

function b() {
console.log(a);
var a = 3;
function a() {};
}
b();
  1. f() {}
  2. undefined
  3. 3

測驗:請問結果為?

function b() {
var a = 3;
console.log(a);
function a() {};
}
b();
  1. f() {}
  2. undefined
  3. 3

測驗:請問結果為?

var b;

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

fn();

console.log(typeof(a), typeof(b));
  1. undefined, undefined
  2. undefined, number
  3. number, number

解答:

typeof

會將 is not defined 回傳 undefined

var b;

function fn() {
var a = b = 3;
console.log(a); // 3
};

fn();
console.log(a); // a is not defined
console.log(typeof(a), typeof(b));

測驗:請問結果為?

function fn() {
a = 2;
var a = 1;
};

var a = 3;
fn();
console.log(a);
  1. 1
  2. 2
  3. 3

測驗:請問結果為?

function fn() {
a = 2;
};

var a = 3;
fn();
console.log(a);
  1. 1
  2. 2
  3. 3

表達式、陳述式

函式陳述式

function foo() {}

函式表達式

var fn = function() {}

測驗:請問結果為?

var x = (y = 10);
console.log(x);
  1. 10
  2. undefined

解答:

(y = 10)  // 這是一個表達式,括號優先執行所以回傳為 10,這個值就賦予到 x。

額外問題:y 是什麼?

1. 被宣告的變數
2. 未宣告的全域變數
3. () 內的區域變數

解答:

y 沒有用 var 宣告,所以不是被宣告變數。
() 不是一個函式,所以不是區域變數。

測驗:請問結果為?

var a = {
a: 10
};

var b = a.a = a.a * a.a;

console.log(b)
  1. 10
  2. 100

解答:

// 不要使用連續賦值
// 這是一個表達式,會回傳值並賦值於 var b。
a.a = a.a * a.a

測驗:請問結果為?

var a = {
a: 10
};

Object.defineProperty(a, 'a', {
writable: false
});

var b = a.a = a.a * a.a;

console.log(b)
  1. 10
  2. 100

解答:

// 會讓 a 物件 裡面的 'a' 屬性的值不能再被賦值
Object.defineProperty(a, 'a', {
writable: false
});

測驗:請問結果為?

var newList = [1, 2, 3].push(4);
console.log(newList.push(5));
  1. [1, 2, 3, 4, 5]
  2. [1, 2, 3, 5]
  3. [1, 2, 3, 4]
  4. Error

解答:

// 這是表達式,回傳值為 4
[1, 2, 3].push(4)
// 正確寫法
var newList = [1, 2, 3];
newList.push(4);
console.log(newList.push(5)); // 5
console.log(newList); // [1, 2, 3, 4, 5]

變數

  • 未宣告的變數會成為全域變數
  • 屬性 可以被刪除,變數 則無法
var a = 1;
b = 2; // window 下的屬性
delete a; // false
delete b; // true

函式內的變數一定要宣告,才可以避免汙染到全域!

// 錯誤寫法
function fn () {
b = 3;
}
fn();
console.log(b); // 3
// 正確寫法
// 有宣告 var 就只會在函式作用域中
function fn () {
var b = 3;
}
fn();
console.log(b); // Uncaught ReferenceError: b is not defined

測驗:請問結果為?

(function() {
var a = b = 3;
}());
console.log(typeof a);
console.log(typeof b);
  1. undefined, number
  2. number, number

解答:

// 因為函式內有宣告 var a 所以外層讀不到值
// 又因為 typeof 保護機制,所以會顯示為 undefined。
console.log(typeof a); // undefined

額外補充

typeof 刪除後重新執行,因為程式是逐行執行,

所以在 console.log(a); 會報錯就停住了。

console.log(b); 就不會執行!

(function() {
var a = b = 3;
}());
console.log(a); // Uncaught ReferenceError: a is not defined
console.log(b);

測驗:請問結果為?

var a;
var b;
(function() {
a = b = 3;
var b;
}());
console.log(typeof a);
console.log(typeof b);
  1. undefined, number
  2. number, number
  3. number, undefined

ASI

ASI:自動插入分號

ex: continue, return, break, throw 後方自動補上分號

不會發生 ASI


測驗:請問結果為?

var a = 1
,b = 2
delete a;
delete b;
console.log(typeof a,typeof b);
  1. number, undefined
  2. number, number
  3. undefined, undefined

測驗:請問結果為?

var a = 10
(function() {
console.log(a)
}())
  1. 10
  2. 10 is not a function

解答:

// 括號 前面不會自動加入分號
var a = 10(function() {
console.log(a)
}())
// 正確寫法
var a = 10;
(function() {
console.log(a) // 10
}())
// 正確寫法
// 或者在 IIFE 前面都加上 ;
var a = 10

;(function() {
console.log(a) // 10
}())

測驗:請問結果為?

function nums(a, b) {
if
(a > b)
console.log('a is bigger')
else
console.log('b is bigger')
return
a + b
}
console.log(nums(4, 2))
console.log(nums(1, 2))
  1. a is bigger, 6 and b is bigger, 3
  2. a is bigger, undefined and b is bigger, undefined
  3. undefined and undefined
  4. SyntaxError

圖片來源: free background photos from pngtree.com