# 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)