JavaScript 筆記 07/14/2018
===
###### tags: `JS` `筆記`
## Node.Js
### 作用
下載後, 假設你有一個 js 程式叫做 `HelloWorld.js`
之後只要下這個指令
```shell=
node HelloWorld.js
```
就可以執行這個程式了
### 我的系統
Ubuntu 16.04
### 安裝
**首先先安裝 NVM (Node Version Manager)**
```shell=
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash
```
這行指令會 clone nvm 到 `~/.nvm`
接下來需要把以下這兩行加到你的設定檔 (`~/.bashrc`)
```shell=
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
```
再來重新 load 一次設定檔
```shell=
source ~/.bashrc
```
檢查 NVM 是否安裝成功
```shell=
command -v nvm
```
只要回應了 `nvm` 就表示成功安裝 NVM 了
**再裝 node.js**
```shell=
nvm install node
nvm use node
```
最後來實測一下功能正不正常, 寫一個 `HelloWorld.js`
```javascript=
console.log('Hello World!');
```
再來下此指令
```shell=
node HelloWorld.js
```
有出現 Hello World 就表示成功安裝了
~~安裝成功or失敗也還麻煩回報一下~~
~~我怕我漏了一些東西~~
:+1::+1::+1::+1::+1:
## 一些 Type 相關的知識
參考以下網址
https://www.ecma-international.org/ecma-262/9.0/index.html#sec-ecmascript-language-types
這裡介紹了 JS 有哪幾種基本 Type
`Undefined` `Null` `Boolean` `String` `Symbol` `Number` `Object`
~~Symbol 未讀~~
### Object Type
一個 `object` 是好幾個 `properties` 組成的
`properties` 分成 `data property` `accessor property` 兩類
`properties` 還有 `attributes` 來定義這些 `properties` 的狀態
`data properties` 有四個 `attributes` : `value` `writable` `enumerable` `configurable`
~~`accessor property` 未讀~~
```javascript=
var object1 = {
property1: 9487
};
console.log(Object.getOwnPropertyDescriptor(object1, 'property1'));
```
執行以上的 code 會得到以下回應
```
{ value: 9487,
writable: true,
enumerable: true,
configurable: true }
```
#### value
代表此 property 裡面放了什麼
#### writable
代表此 property 的 value 是否可以改寫
#### enumerable
這個跟後面迴圈寫法有關, 放到後面說
#### configurable
代表此 property 的 attributes 是否可以重新設定
以下 code 將設定一個 wriatable 為 false 的屬性
```javascript=
var object1 = {};
Object.defineProperty(object1, 'property1', {
value: 48,
writable: false // 等等可以改成 true 再測試看看
});
console.log(Object.getOwnPropertyDescriptor(object1, 'property1'));
// 嘗試改改看 property1 的 value
object1.property1 = 87;
console.log(Object.getOwnPropertyDescriptor(object1, 'property1'));
```
執行後, 得到以下結果
```
{ value: 48,
writable: false,
enumerable: false,
configurable: false }
{ value: 48,
writable: false,
enumerable: false,
configurable: false }
```
value 沒有變, 因為 writable 為 false
> 參考此網站
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty
Object.defineProperty 可以用來定義一個 `object` 的 `property` , 若 `property` 已經存在, 則這個函式則會更改該 `property` 的各個 `attributes`
用此函數定義 `property` , 若有`attribute`沒有被定義到要給什麼值,像是這個例子 , 只有設定`value` 跟 `writable`, 沒有定義 `enumerable` `configurable` , 此網站裡面也都有說預設會給什麼值
## 迴圈寫法
> while, do-while, 以及最基礎的 for 都與 C 語言一樣, 所以就不寫了
主要討論 for-in 跟 for-of 的差別
### for-in
參考了這個討論串
https://stackoverflow.com/questions/29285897/what-is-the-difference-between-for-in-and-for-of-in-javascript
裡面說道
> for-in iterates over all non-Symbol, enumerable properties of an object.
#### 實驗1
```javascript=
var myArray1 = ['String', true, 689];
for (let i in myArray1) {
console.log(i);
}
var myObject1 = {
name: 'Ming',
age: 8,
weight: 300
};
for (let i in myObject1) {
console.log(i);
}
```
會得到
```
0
1
2
name
age
weight
```
#### 解釋1
for-in 會 loop 一個 `object` 的 `properties name`
若對象是 `array` , 則會 loop index
#### 實驗2
```javascript=
var myObject1 = {
name: 'Ming',
age: 8,
weight: 300
};
Object.defineProperty(myObject1, 'name', {
enumerable: false
});
for (let i in myObject1) {
console.log(i);
}
```
得到
```
age
weight
```
#### 解釋2
回頭看一下這句
> for-in iterates over all non-Symbol, enumerable properties of an object.
因為 `name` 的 `enumerable` 被設定成 false
所以他不會被 for-in loop 到
##### 有時間可以再自行測試
- Array Like Object
### for-of
參考此網頁
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of
> The for...of statement creates a loop iterating over iterable objects
#### 實驗
```javascript=
var myArray1 = ['String', true, 689];
for (let i of myArray1) {
console.log(i);
}
var myObject1 = {
name: 'Ming',
age: 8,
weight: 300
};
for (let i of myObject1) {
console.log(i);
}
```
得到
```
String
true
689
TypeError: myObject1 is not iterable
```
#### 解釋
for-of 會 loop `array` 的各個 value
但卻不適用 `object`
根據這篇文
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#The_iterable_protocol
> The iterable protocol allows JavaScript objects to define or customize their iteration behavior, such as what values are looped over in a for..of construct. Some built-in types are built-in iterables with a default iteration behavior, such as Array or Map, while other types (such as Object) are not.
> In order to be iterable, an object must implement the @@iterator method, meaning that the object must have a property with a @@iterator key which is available via constant Symbol.iterator
簡單來說, 若一個 `object` 沒有定義 `Symbol.iterator` method, 或是有定義卻不符合 `Iterator protocol` , 那就不能用 for-of
## Array vs Object
```javascript=
// Array 寫法
var myArray1 = ['Hello', true, 5487];
// Insert 有兩種方法
myArray1[3] = 'FirstWay'
myArray1.push('SecondWay');
// Access
console.log(myArray1);
console.log(myArray1[4]);
// Object 寫法
var myObj = {
msg: 'Hello',
flag: true,
value: 58487
};
// Insert 也有兩種方法
myObj['Name'] = 'Ming';
myObj.Age = 8;
// Access
console.log(myObj);
console.log(myObj.Age);
// 判斷是否為 Array
// 有兩種方法
// First Way
console.log(Array.isArray(myArray1));
console.log(Array.isArray(myObj));
// Second Way
console.log(myArray1 instanceof Array);
console.log(myObj instanceof Array);
```
執行結果如下
```
[ 'Hello', true, 5487, 'FirstWay', 'SecondWay' ]
SecondWay
{ msg: 'Hello', flag: true, value: 58487, Name: 'Ming', Age: 8 }
8
true
false
true
false
```
## Generator (function*)
參考此篇
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator
寫了一個怪怪的 code
```javascript=
function* generator(i) {
yield i;
yield i + 10;
}
var gen = generator(10);
console.log(gen.toString());
console.log(typeof gen);
console.log(gen.next().value);
console.log(gen.next().value);
```
得到結果
```
[object Generator]
object
10
20
```