# Java Script 1201 ``` var a = 1 function x() { var a = 2; console.log(a); } console.log(a) ``` * 遮蔽,會印出2,1 2是function印出,1是第一行的a值 * function內的console.log(a)會先從function內找a,沒有才會再向外部找 * ;可加可不加,不要任意換行(ASI = Auto Semicolon Insertion執行時會自動加上)會導致出錯或用()包住 =================== # lexical scope ``` var x = 1; function a() { console.log(x); } function b() { var x = 2; a(); } b(); ``` 結果印出1 執行過程: 執行b() ->function b() -> var x = 2 -> 執行a() -> console.log(x) ->因為function a()內沒有x,向外部找var x = 1 * JS可以function包function並非把function但這裡不是將a()塞進b()內執行,所以不會找到var x = 2 ============================== var最小存活限制範圍是function let最小存活限制範圍是Block {} const最小存活限制範圍是Block {} var a = 1 var a = 2 a會被覆蓋變成2 let a = 1 let a = 2 不能在同範圍內重覆宣告,報錯Cannot declare a let variable twice: 'a'. const A = 1 宣告常數A,大小寫都可以但通常用大寫表示 const score = 1 score = 2 不能被re-assign const score = [1,2,3] score[0] = "x" consloe.log(score) 印出[x,2,3] 可以修改[]內的東西 *被const宣告指向的容器是不能改變,但容器內的東西可以改變 consle x --> 1,consle x --> [...] 不能改的是“-->指向的容器”,容器的內容可以改,1就是1沒有容器所以不能改,[]本身也不能改,但容器[]內部可以改變 =============================== *JS是一種單一執行緒會逐行執行程式 single thread console.log(1) setTimeout(function(){ console.log(3); },2000); console.log(2) 結果為印出1,2,最快兩秒後再印出3 執行過程: console.log(1)進入stack執行完後移出stack --> setTimeout讓出控制權先執行console.log(2)並計算兩秒後進入Queue等待stack清空 -->console.log(2)進入stack執行完後移出stack --> stack清空console.log(3)進入stack執行 setTimeout會讓出控制權先執行下一行程式,本身會在等待兩秒後再進入Queue排隊等待stack空了才能回來,所以全部時間為兩秒加上等待stack空置的時間 當有多個setTimeout時,先計時行完畢的會先進到Queue排隊等待,與setTimeout在程式中的順序無關 參考[http://latentflip.com/loupe/] ============================== 在`$node`可以練習JS typeof()可以查詢型別 > typeof(2) 'number' > typeof(typeof(2)) 'string' > typeof({}) 'object' > typeof(undefined) 'undefined' > typeof(null) 'object' 注意 > 1 == "1" > true 兩個等號字串會轉型別再比較 > 1 === "1" > false 三個等號直接比較型別 實際上兩個等號和三個等號都會比較型別 1 == 1 當同型別時會轉到1 === 1做比較 1 == "1" 不同型別時會先轉換型別 再轉1 === 1比較得到true 所以實際上兩個等號和三個等號都會比較型別 參考JS手冊7.2.14 Abstract Equality Comparison ============================ > typeof(NaN) 'number' >NaN === NaN 'false' NaN是唯一自己不等於自己的"number" ``` var input = 1/'a'; if (input === NaN) console.log("ok") else console.log('1') end ``` 這裏input是NaN但是沒有任何東西可以等於NaN,所以永遠得到false 只走else 要判斷是否為NaN有專屬語法isNaN()所以要寫成 ``` var input = 1/'a'; if (isNaN(input)) console.log("ok") else console.log('1') end ``` undefined、null、false、NaN幾種為false ========================== 嚴格模式`"use strict"`只能寫在整個文件開頭或function的第一行,用字串寫可以讓不支援的瀏覽器避免報錯(只當作一般字串) ========================== Expression表達式 vs Statement陳述句 查維基 ========================== ``` function a() { return 2 } console.log(a) ``` 在JS中function也是一種物件,上述就是把function當參數傳給console.log而不會執行,會印出 function a() {return 2} 也就是整個function原貌而不是執行function a() ``` function a() { return 2 } console.log(a()) ``` 代入a()會先執行function得到2的回傳值,再代入console.log會印出2 ============================== Higher Order Function 可以接受其他function當參數的function,是一個相對於當參數的function的稱呼 ========================= act1: 'aa' act2: 'bb' act3: 'cc' var y = 3 console.log(obj['act' + y]) 動態['act' + y]會合併轉為字串(跟兩個等於比較時會轉數字不同==>JS手冊規定) 一般用obj.act1就可以取 數字開頭不是合法的名稱 1aa: 'bbb',可以設定但不能用.1aa取用,要用['1aa'] =========================== var obj = { name: 'kk', attack: function(){ consloe.log(`hi`); //template literal } } var obj = {} 同 var obj = Object.create(null) obj.name = "aa" obj.age = 18 obj.attack = function() { console.log('hi'); } console.log(obj) =========================== const goku = heroCreator('悟空', 100) console.log(goku) goku.attack() function heroCreator(name, power) { // return { // name, // power, // attack: function() { // console.log(`${this.name} 造成 ${this.power} 點的傷害`); // } // } const hero = {} hero.name = name hero.power = power hero.attack = function() { console.log(`${this.name} 造成 ${this.power} 點的傷害`); } return hero; } =========================== const goku = heroCreator('悟空', 100) console.log(goku) goku.attack() function heroCreator(name, power) { const hero = {} hero.name = name hero.power = power hero.attack = function() { console.log(`${this.name} 造成 ${this.power} 點的傷害`); } return hero; } =========================== const list = [1,2,3,4,5] function even(x) { return x * 2 } const result = list.map(even) console.log(result)