什麼是Node.js ?
Node.js是許多新創公司選擇的開發語言,跟它的開發生態有關
因為JavaScript在網頁開發上幾乎很難短時間被取代
作為㇐個後端開發它又有豐富的套件生態,甚至前端套件也可以運用在後端,所以只要了解套件 使用,就可以快速開發
Node.js 特性
- 得益於V8引擎,效能卓著
- 採用異步(非阻塞) I/O ,不會有因為同步(阻塞) I/O導致效能急遽下降的問題
- JavaScript 固有的事件驅動、閉包等語言特性,使用起來非常方便
- Node.js 可跨平台在 Windows、Linux 及 Mac OS X 系統運行
補充
- 垃圾回收機制(GC)
Node.js會主動做垃圾回收
開發者仍須注意記憶體洩漏
例如無窮迴圈或是閉包的使用失當
- 閉包(Closure)
function getCount(i) {
var count = i;
var calculate = function(){
console.log(count);
count++;
};
return calculate;
}
var displayCount = getCount(0);
displayCount();
displayCount();
displayCount();// 0
// 1
// 2
因為變數count還有被另㇐個內部函式引用
所以變數count的生命週期會在每次getCount被呼叫而延⾧,不會被回收
- 非同步非堵塞IO
var readFile = function (cb) {
setTimeout(function () {
cb('file content:hello async function');
}, 5000);
}console.log('dosomethingAAA');readFile(function (file) {
console.log(file);
})console.log('dosomethingBBB');// dosomethingAAA
// dosomethingBBB
// file content:hello async function
Synchronous (同步) , Asynchronous (非同步)
Node.js相當多API都有提供 callback function 以避免阻塞
非同步處理是Node.js㇐大特色
- Promise Async/Await
var threeSecLater = function () {
return new Promise(function (resolve, reject) {
setTimeout(function () {
console.log('3 sec later');
resolve();
}, 3000);
});
}
var fourSecLater = function () {
return new Promise(function (resolve, reject) {
setTimeout(function () {
console.log('4 sec later');
resolve();
}, 4000);
});
}
;(async() => {
await threeSecLater();
await fourSecLater();
})();// 3 sec later
// 4 sec later
// 共7秒
讓函式 return Promise 物件
藉由 async/await 的語法,讓非同步 function 變成同步執行
什麼是全域執行環境 ?
「全域」指可在區域裡、JavaScript 檔案裡、詞彙環境裡被取用
全域執行環境創造的兩個東西
- 全域物件(Global Object),
window
- 特殊變數
this
全域物件(Global Object)
「程式碼或者變數不再函式裡就是全域的」
console.log(this);
// Window {0: global, window: Window, self: Window, document: document, name: “”, location: Location, …}
特殊變數(this)
this是JavaScript程式在執行時的綁定(runtime binding),與函式在何處宣告無關,而是取決於函式被呼叫的方式以及地點
var x = 10;
var obj = {
x: 20,
fn: function() {
var test = function() {
console.log(this.x);
};
test();
};
};
obj.fn();// 10
- 脫離物件的 this 基本上沒有任何意義
- 沒有意義的 this 會根據嚴格模式以及環境給一個預設值
- 嚴格模式底下預設就是 undefined,非嚴格模式在瀏覽器底下預設值是 window
- 可以用 call、apply 與 bind 改變 this 的值
- 要看 this,就看這個函式「怎麽」被呼叫
- 可以把
a.b.c.hello()
看成a.b.c.hello.call(a.b.c)
,以此類推,就能輕鬆找出 this 的值
理解 JavaScript 中的事件循環、堆疊、佇列和併發模式
(Learn event loop, stack, queue, and concurrency mode of JavaScript in depth)
- 堆疊(stack)
function multiply(a, b) {
return a * b
}
function square(n) {
return multiply(n, n)
}
function printSquare(n) {
let squared = square(n)
console.log(squared)
}
printSquare(4)
- 無窮迴圈
function foo () {
return foo()
}
foo()
- 阻塞(blocking)
// pseudo code
var foo = $.getSync('//foo.com')
var bar = $.getSync('//bar.com')
var qux = $.getSync('//qux.com')
console.log(foo)
console.log(bar)
console.log(qux)
阻塞的情形導致瀏覽器停滯
- 非同步處理與堆疊(Async Callback & Call Stack)
console.log('hi')
setTimeout(function () {
console.log('there')
}, 5000)
console.log('JSConfEU')
- 並行和事件循環 ( Concurrency and Event Loop )
程式執行時,依序將函式放入呼叫堆疊(Call Stack)
如呼叫到Web APIs相關函式則將其回呼函式放入回呼佇列(Callback Queue)等待叫用。
回呼時機來臨時,才將回呼函式放入呼叫堆疊(Call Stack)執行
setTimeout 是JS引擎提供的函式,可預約若干時間後,執行特定函式
setTimeout 非常重要,JavaScript在 ES6 提供的 Promise 的底層就是有使用到 setTimeout
setTimeout 0 ?