Slide 1

Slide 1 text

Advanced JS and Node.js NTU CCSP 2012 FALL

Slide 2

Slide 2 text

Outline • 物件導向?! new // Function // instanceof • 物件導向2 prototype • ECMA5的好東西 Array.xxx Object.xxx

Slide 3

Slide 3 text

JS物件導向 • JS沒有class但有new • JS沒有class但有instanceof • JS沒有class但有prototype

Slide 4

Slide 4 text

回到資料型態 • Primitive Type ◦ string ◦ number (NaN Infinity) ◦ boolean • Composite Type ◦ Object ◦ Array ◦ String ◦ Number ◦ Boolean • Special Type ◦ null ◦ undefined typeof() 都是 function

Slide 5

Slide 5 text

函數的三種建構方式 function isthisfunction() {} var isthisfunction2 = new Function(); var isthisfunction3 = function(){}; console.log(typeof(isthisfunction)); console.log(typeof(isthisfunction2)); console.log(typeof(isthisfunction3)); 所有函數都是物件 但物件不一定是函數

Slide 6

Slide 6 text

函數作為建構子 function funca() {} var obja = new funca(); console.log(typeof(funca)); console.log(typeof obja); console.log(obja instanceof funca); function Person(name, age) { this.name = name; this.age = age; } var p1 = new Person('Justin', 35); var p2 = new Person('Momor', 32); console.log(p1 instanceof Person); typeof funca = function typeof obja = object obja instanceof funca = true 判斷物件的class要用 instanceof 而不是 typeof

Slide 7

Slide 7 text

What is this ? function fn( arg1, arg2,... ){ // do something } fn( arg1, arg2,... ); fn.call(context, arg1, arg2,... ); fn.apply(context, [ arg1, arg2,... ]); this就是apply與call的第一個參 數 都沒有指定時取決呼叫方式 物件呼叫帶物件本身 非物件呼叫帶全域變數

Slide 8

Slide 8 text

呼叫方式對this的差異 var obj = { fn : function() {console.log(this)} }; obj.fn(); var tmpfn = obj.fn; tmpfn(); 第一個會印空物件 第二個會印很多東西 取決於執行環境

Slide 9

Slide 9 text

回頭看 function Student(school) { this.school = school; } var stu1 = {school : 'NTU'}; var stu2 = new Student('NCKU'); console.log(typeof stu1); console.log(typeof stu2); console.log(stu1 instanceof Student); console.log(stu2 instanceof Student); 你可以想像成 new Student就是 呼叫Studen且context設成一個空物 件 object object false true

Slide 10

Slide 10 text

原形鍊詳解 function Person(name) { this.name = name; } var p1 = new Person('Steven'); console.log(p1); console.log(p1.__proto__); console.log(p1.__proto__ === Person.prototype); console.log(p1.__proto__.__proto__); console.log(p1.__proto__.__proto__ === Object.prototype); Person p1 Person.prototyp e new Object new Object.prototype { name: 'Steven' } {} true {} true

Slide 11

Slide 11 text

原型練應用於物件方法 function Person(name) { this.name = name; } Person.prototype.like = function(another) { if(!(another instanceof Person)) throw new Error('Not Person'); if(another == this) throw new Error('can not like myself'); this.likewith = another; another.likewith = this; }; var p1 = new Person('Steven'); var p2 = new Person('Jobs'); p1.like(p2); console.log(p1); console.log(p2); { name: 'Steven', likewith: { name: 'Jobs', likewith: [Circular] } } { name: 'Jobs', likewith: { name: 'Steven', likewith: [Circular] } }

Slide 12

Slide 12 text

原型練應用於繼承 function Person(name) { this.name = name; } Person.prototype.like = function(another) { if(!(another instanceof Person)) throw new Error('Not Person'); if(another == this) throw new Error('can not like myself'); this.likewith = another; another.likewith = this; }; function Superman(name, superpower) { this.superpower = superpower; Person.call(this, name); } Superman.prototype.__proto__ = Person.prototype; Superman.prototype.usesuperpower = function() { console.log(this.name + ' use "' + this.superpower + '"'); } var hulk = new Superman('HULK001', 'green and big'); hulk.usesuperpower(); HULK001 use "green and big"

Slide 13

Slide 13 text

原型練應用於繼承 Person Person.prototyp e Object.prototype Suprman Suprman.prototy pe hulk new call

Slide 14

Slide 14 text

助教我炸裂了! 撐下去 hasOwnProperty isPrototypeOf var hulk = new Superman('HULK001', 'green and big'); console.log(hulk.hasOwnProperty('name')); console.log(hulk.hasOwnProperty('usesuperpower')); console.log(hulk instanceof Superman); console.log(Person.prototype.isPrototypeOf(hulk)); true false true true 不是自己的特性 hasOwnProperty會回傳 false

Slide 15

Slide 15 text

還有更讓你炸裂的特性 function Person(name) { if(name) this.name = name; } Person.prototype.name = 'ONE MAN'; var p1 = new Person(); console.log(p1.name); p1.name = 'Mike'; console.log(p1.name); var p2 = new Person(); console.log(p2.name); 讀取會follow原型練 寫入不會 ONE MAN Mike ONE MAN

Slide 16

Slide 16 text

我的意見 • 物件導向的所有特性(類別 繼承 封裝 多形) Javascript都能達成 • 但很少專案會完全導入OOP • 語法本質 => 我不這樣寫還是可以正確交付 • code會變很多 • 如果依賴OOP框架 => 可閱讀性與可移植性變低

Slide 17

Slide 17 text

ECMA5的好東西 • Array Utilities • Object Getter • Object Setter • …

Slide 18

Slide 18 text

Object.keys var obj = { a : 'AAA' , b : 'BBB' } for(var key in obj) { console.log('obj[' + key + ']=' + obj[key]); } obj.__proto__.c = 'CCC'; for(var key in obj) { console.log('obj[' + key + ']=' + obj[key]); } console.log(Object.keys(obj)); obj[a]=AAA obj[b]=BBB obj[a]=AAA obj[b]=BBB obj[c]=CCC [ 'a', 'b' ] Object.keys不會走prototype chain For-in會

Slide 19

Slide 19 text

Array in ECMA5 var arr = [1, '2', 3]; console.log(arr.map(function(ele){return ele*3})); console.log(arr.filter(function(ele){return ele > 1})); arr.forEach(function(ele, index){console.log('arr[' + index + ']=' + ele)}); console.log(arr.every(function(ele){return ele > 2})); console.log(arr.some(function(ele){return ele > 2})); console.log(arr.reduce(function(prev, curr){return prev + curr})); [ 3, 6, 9 ] [ '2', 3 ] arr[0]=1 arr[1]=2 arr[2]=3 false true 123 Map Reduce 正夯

Slide 20

Slide 20 text

還有更多… • Object.seal • Object.freeze • enumerable and non- enumerable properties • M$開發者上MSDN JS開發者請上MDN

Slide 21

Slide 21 text

中場休息

Slide 22

Slide 22 text

Outline • 介紹是一定要的 • 非同步程式 • 安裝 • 模組機制 • 簡單檔案讀取 • 簡單網頁伺服器

Slide 23

Slide 23 text

瀏覽器裡的Javascript • 語法來自ECMAScript ◦ 由歐洲電腦製造商協會維護 ◦ 目前第五版 ◦ 第六版快了 • BOM, Browser Object Model ◦ AJAX, Local Storage, WebGL, Web Audio, WebRTC ◦ W3C維護 • DOM, Document Object Model ◦ W3C維護

Slide 24

Slide 24 text

Node.js • 語法使用 ECMAScript v5 • 模組機制 • 檔案 檔案系統 網路 程式 • 使用Google的V8 Engine • 編譯成native code執行 • 非常重要 => stop-world GC

Slide 25

Slide 25 text

同步 (絕大多數) 非同步 (這幾年變紅很多) 非同步與同步 IO wait IO wait IO IO cmpl IO IO cmpl 非同步會變成多個指令流 像是同步的多執行緒 然而多指令流不代表concurrent 喔

Slide 26

Slide 26 text

比較 同步 非同步 切換context 中斷(IO Wait, time sharing) 一路玩到掛 平行化 TLP PLP 同步機制 Lock, conditional wait, … Send / wait 同步成本 低 高 單一核心使用效率 低 高

Slide 27

Slide 27 text

安裝 1. Windows只要一直按next 2. Mac同上 3. Linux建議使用nvm, Node Version Manager • 推薦優先順序 ◦ Linux > Mac > Windows • 密技 Cloud9 https://c9.io/

Slide 28

Slide 28 text

Demo

Slide 29

Slide 29 text

模組機制 • require(‘模組名稱’) • require(‘相對路徑’)

Slide 30

Slide 30 text

讀取檔案 var fs = require('fs'); console.log(fs.readFileSync(__filename, 'utf-8')); fs.readFile(__filename, 'utf8', function(err, data) { console.log('async readFile:\n'); console.log(data); }); 用Sync請改去用 Python/PHP/Ruby

Slide 31

Slide 31 text

HTTP Server var http = require('http'); http.createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Hello World\n'); }).listen(process.env.PORT); 萬年老梗

Slide 32

Slide 32 text

結合兩者 var http = require('http'); var fs = require('fs'); http.createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/html'}); fs.readFile('.' + req.url, 'utf8', function(err, data){ res.end(err ? err.toString() : data); }); }).listen(process.env.PORT); Callback hell 下周待續