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 ```