Open zuppachu opened 6 years ago
可以看 Peggy 的筆記 非常詳細 :)
Node.js 內建很多模組(Module),而模組化就是把功能分堆,以便之後好維護。 例如:把主程式裡面分為:登入功能 + 金流功能 + 會員功能 + 權限功能。 之後可能哪一部分壞了就修那一塊,不會干擾到其他功能。
模組化好處小結:
把別人寫好的功能,用 require
引入進來。
var os = require("os")
// "os" 這個被字串包起來的 os 是我要引入的名稱
// 引入進來後,變數(os)名稱可以改
console.log(os.platform())
// darwin => MAC OS 的核心名稱
(這單元講:如何自己做出一個 module 讓自己和別人使用?)
輸出一個東西時
記得先新建檔案:myModule.js + index.js
例一:
//在 myModule.js
function double(n) {
return n * 2
}
module.exports = double
//要輸出一個 module 給別人使用,用 module.exports = 接你想要輸出的東西
//module.exports 輸出什麼,之後再 index.js require 就會是接收什麼
//在index.js
var ABC = require("./myModule.js")
// "檔案路徑" ,("./myModule.js") 可以不寫 .js,寫("./myModule")也可以
console.log(ABC(3))
//得6
例二
//在 myModule.js
module.exports = 123
//用這個方式,想要另一邊輸出數字,就會輸出數字
//在index.js
var test = require("./myModule.js")
console.log(test)
//得123
例三
//在 myModule.js
module.exports = [1, 2, 3] //用這個方式,想要另一邊輸出陣列,就會輸出陣列
//在index.js
var KKK = require("./myModule.js")
console.log(KKK)
//[1, 2, 3]
//在 myModule.js
function double(n) {
return n * 2
}
var obj = {
double: double,
triple: function(n) {
return n * 3
}
}
module.exports = obj //變成物件的方式
或是這種寫法,但意思與上面一樣。
function double(n) {
return n * 2
}
module.exports = {
double: double,
triple: function(n) {
return n * 3
}
}
module.exports = obj
或另一種方法:
function double(n) {
return n * 2
}
//用此寫法 exports .XXX,XXX必得是物件(object)
exports.double = double
exports.triple = function(n) {
return n * 3
}
//在index.js
var ABC = require("./myModule.js")
console.log(ABC.double(2), ABC.triple(10))
//得 4 30
當你寫好一個功能時,可以把它包裝成 package/ library/ module,上傳給全世界的人使用。 當然,我們也可以透過 NPM 幫忙管理這些套件們。可以想像成一個大型倉庫專門存套件的地方。
在 iTerm 寫下:
npm init
:
初始化。處理完會多一個 package.json
的檔案
(= 一個描述資料 json格式的檔案/A file that contains information about a JavaScript project.)
npm install left-pad
:
安裝 left-pad => 打 ls => 會發現在 mentor-program 裡面多一個 node _modules 資料夾。
(但這種方式不太好,因為當你下載太多個套件,上傳給別人時,會造成別人檔案太大的困擾,倒不如跟別人說:喔,我有用 left-pad,你可上自己抓!所以用下面的方法比較好。)
npm install left-pad --save
:
安裝 left pad 套件至 node_modules 資料夾中,並將資訊存在 package.json
裡的 dependencies 中。(從 npm 5 以後,--save 就已經變成預設的選項了,因此 npm install 不加 --save 也是可以的喔,一樣會把資訊寫到 package.json 裡面去!)
npm install left-pad --save-dev
:
devDependencies 指開發時才會用到的 library,正式環境上不會用到的 library (與 --save 差別微乎其微。)
npm -v
:檢視有無裝成功,會顯示一串數字代表版本。
PS:切記要在上傳專案時,要把 node-module 用 .gitignore
排出在外,因為真的太大了,會造成對方困擾,對方需要時可以再用 npm install
這個指令會直接幫忙把需要的套件抓下來。其背後的原理是因為 npm 會自動檢查 package.json
檔案內的 Dependencies
欄位。
在你要使用此 module 的 .js 檔案中
var abc = require("left-pad") //使用left pad 這個 module console.log(abc(123,10,"0") //得 0000000123
當專案變大,有太多檔案,每個都看起來很像入口點/該執行的檔案時,有兩種方法:
"main"
區塊,先寫好該開啟的檔案。“scripts”
區塊"scripts": {
"start": "node index.js", //在 iTerm 中用 nmp 執行 start 時,它就會幫你執行後面你寫好的檔案(npm run star)
"yoyoyo": "echo 123"
}
//在 iTerm 中
打 npm run start //就會執行 node index.js
打 npm run yoyoyo // 結果就會是 123
FB 開發的,大致相同於 npm
npm install -g yarn
; 不行的話用 sudo npm install -g yarn
yarn init
等同於 npm init
yarn
等同於 npm install
yarn add left-pad
等同於 npm install left-pad --save
單元測試,就是利用自動化方式測試程式內的小單元(如: function 、method、class 等)
就是為了減少 debug 時間呀~
A:
由於點一與點二的缺點是很難規模化!故用別人已經寫好的測試框架,例如: Jest 框架。
首先,先裝 jest,有兩種方式:
yarn add --dev jest
npm install --save-dev jest
再來將 package.jason
裡的 "scripts": { "test": "..." }
,改為 { "test": "jest" }
。
寫測試檔 xxx.test.js
(通常會將測試檔案命名為 xxx.test.js
),如下:
在有 xxx.test.js
檔案的資料夾中,跑 npm run test
。(nmp 不是 globel 的,他只會跑在某個專案底下的 test 檔)
npm run test
:會跑全部命名為 test 的檔案 我用npx jest hw1.test.js
跑個個小測驗 或是npx jest test
也是跑全部有命名為 test 的檔案。
npx
是新一點的版本
例一:
// 在 hw1.js中
function stars(n) {
var result = ["*"]
for (var i=2; i<=n; i++){
result.push("*".repeat(i))
}
return result
}
module.exports = stars;
在 hw1.test.js中
var stars = require('./hw1')
describe("hw1", function() {
it("should return correct answer when n = 1", function() {
expect(stars(1)).toEqual(['*'])
// .toEqual 也可改寫成 .toBe
})
})
例二:
//在 index.js 中
function repeat(str, times) {
var result = ""
for (var i=0; i<times; i++){
result += str
}
return result
}
module.exports = repeat;
//在 index.test.js中
var repeat = require('./index.js')
//可以寫成一個比較模組的感覺,如下:
describe("測試 repeat", function() {
test("a 重複 5 次應該要等於 aaaaa", function() {
expect(repeat("a", 5)).toBe('aaaaa')
})
test("abc 重複 1 次應該要等於 abc", function() {
expect(repeat("abc", 1)).toBe('abc')
})
test(""" 重複 10 次應該要等於 """, function() {
expect(repeat("", 10)).toBe("")
})
})
先寫測試再寫程式方式:
參考: [Javascript] 關於 JS 中的淺拷貝和深拷貝 [筆記] 談談JavaScript中by reference和by value的重要觀念
深拷貝 = 全部東西都複製「值」而已 淺拷貝 = 第一層複製值,第二三四五六七八之後的層都是複製「記憶體位置」 展開運算子是淺拷貝,故只對第一層有用。
ES6 語法
呼呼~ 好不容易進入到第二階段的 javaScript,看的速度跟不上筆記的速度!安捏姆後!趁記憶力還在時,趕快做筆記才是王道!
什麼是 作用域(scope)?
作用域代表一個變數的生存範圍 = 超過這個生存範圍,此變數就不存在了。
作用域分為:
以下例子為 function scope 無法再 global scope 中顯示:
變數在不同 scope 裡的生存範圍:
宣告變數時一定要加 var,否則 JavaScript 會把此變數自動改成全域變數,容易產生 bug :
const、let 與 var
const
: 全名為constant = 常數,給定值後就不能改變,例如:colors.push('red'); colors.push('blue');
colors = 'Green'; //typeError: Assignment to constant variable.
console.log(colors);
let
:跟var
相似。只是作用範圍有差異。let
與const
:區塊作用域 (block scope = 大括號{ }
的區塊範圍內)var
是函式作用域 (function scope = 生存於一個 function 範圍內)來看一些程式碼,比較容易理解~
例一:
例二:
例三:
箭頭函式 Arrow function
以下四種寫法皆相同:
Template string
解決字串相加太多時,造成可讀性不高的問題。
簡而言之,省去
+
。讓字串用、
(backtick) 包起來後,把變數放入$
{}
(大括號) 裡面。然後另外個好處是:可以換行 !不像 ES5 一換行等於失誤。
解構 Destructuring
將用陣列與物件展示如何解構:
var first = arr[0] var second = arr[1] var third = arr[2] var fourth = arr[3]
console.log(second, third) //得2,3
//ES6 語法 const arr = [1,2,3,4] var [first, second, third, fourth] = arr //對應的方式,配對! console.log(second, third) //得2,3
就還是得用對應的方式(按照位置)讓程式理解你想要取的值。
//ES5 語法 var name = obj.name var age = obj.age
console.log(age)
上面寫法也等同做了兩件事:
//對應版 var { family: { father } console.log(father)
console.log(arr2) //得 [ 4, 1, 2, 3, 5, 6 ]
console.log(arr === arr2) // true 因為記憶體位置一樣
const arr = [1, 2, 3]
const arr2 = arr arr2[0] = 10
console.log(arr) //得 [10, 2, 3],因為他們是指到同個記憶體位置。
補充處
二、 物件
表示方式
名稱重複時,程式碼以下面宣告的優先:
展開運算子也可當作引數
var arr = [1, 2, 3] console.log(add(...arr)) //得 6
反向展開:Rest Parameters
給我剩下的東西~ (...XXX)
console.log(add(1, 2)) // [ 1, 2 ] // 3
參數預設值:Default Parameters
Import 與 Export
ES5 寫法:
ES6寫法:
或可以這樣寫
Babel
A JavaScript package that transpiles JavaScript ES6+ code to ES5.