# JS Pattern
# 重要概念
use strict
嚴格模式JS
沒有 class避免全域變數 (要用 var)
- Why ?
- 避免用全域變數讓你的 code 更 portable
- How ?
- 忘了用 var 會不經意的生出
全域變數
- 使用命名空間 (namespace)
- 用自我執行的立即函示 (immediate function)
- 忘了用 var 會不經意的生出
- Why ?
var
vslet
vsconst
?let
為ES6
之後新增的宣告概念- var 的作用域在 function 內, 但 let 作用域在區塊之內
- var 在同名的情況下, 區域變數可能會蓋到全域變數
let
不可重複宣告, 會錯,var
可以const
-> 如果宣告後 不會重新賦值, 使用 const
JS
Hoisting
問題
# JS Functions
- Function statement (函數陳述句)
- 一開始 JS就整個 Load進 記憶體內
- 單純陳述, 需要呼叫才會執行
function greet(name){
console.log('Hello' + name);
}
greet();
1
2
3
4
2
3
4
- Function expression (函數表示句)
- 一開始不會放在記憶體內, 當執行到該行的時候,才會創造並且執行
var greetFunc = function(name){
console.log('Hello' + name);
}
greetFunc();
1
2
3
4
2
3
4
- IIFE
- 類似函數表示句, 只是在後面加了一個括號, 表示創造後 立刻執行
var greeting = function(name){
console.log('Hello' + name);
}();
1
2
3
2
3
- IIFE 改
var greeting = function(name){
return 'Hello' + name;
}();
1
2
3
2
3
- 在此情況下, greeting 是一個 string (Function執行後的結果), 而不是 function
# IIFE 的特性
- IIFE 內的變數,有自己的執行空間, 不會受外面影響, 亦不會影響到外部
- 安全的程式碼
- 套件多會使用IIFE的寫法
- 如果一定要用全域變數, 可以用傳的方式將 window 物件傳進去
# Closure
function buildFunction(){
var arr = [];
for (var i=0;i<3;i++){
arr.push(function(){
console.log(i);
})
}
return arr;
}
var fs = buildFunction();
fs[0]();
fs[1]();
fs[2]();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
- 這個例子的結果, 會輸出 (3,3,3) 而非 (1,2,3)
- 因為 function()內 console.log 並非馬上執行
- forloop內先把三個 function 丟進去(裡面有console.log指令)
- forloop跑完, i=3
- 底下 fs 時,會去呼叫
- Reference 去找 console.log(i), 此時 i都為3
- console.log是在底下 fs呼叫時才執行, 而非 loop內. 此時i已經都為 3