6. 6
變數
規則
└ 第一個字元不可是數字
└ 只能是字母、底線和錢字號
└ 不可為關鍵字
└ 如 If、for、this 等等
└ 區分大小寫
└ myname、MYNAME 為不同變數
└ 慣例使用小駝峰命名
└ 如 myName、mySchool
└ 無型別
└ 以逗號分隔多個變數
關鍵字
└ var
└ let
└ 只有在 let 宣告的範疇中有效
└ 沒有變數提升 (hoisting)
└ const
└ 用來宣告常數
└ 宣告時需指定值
└ 沒有變數提升 (hoisting)
// 正確
var myName;
var _func;
var $i;
// 錯誤
var 01x;
var @test;
var #dash;
var a = 10,
b = 'test';
7. 7
變數範疇
一個變數的範疇 (scope) 是指程式碼中該變數有定義的區域
└ JavaScript 有兩種變數範疇:全域變數和區域變數
└ 區域變數的優先序比同名稱的全域變數高
└ 使用 var 在函式內宣告的變數為區域變數
└ 使用 let 在函式、for 區塊、if 區塊、或純區塊內宣告的變數為區域變數
var scope = 'global';
function checkScope() {
var scope = 'local’;
console.log(scope); // local
}
checkScope();
console.log(scope); // global
let x = 1;
if (true) {
let x = 2;
console.log(x); // 2
}
console.log(x); // 1
var x = 1;
if (true) {
var x = 2;
console.log(x); // 2
}
console.log(x); // 2
8. 8
變數提升
console.log(a);
var a = 10;
console.log(a);
undefined
10
變數宣告會被提升 (hoisting) 到該範疇的最上方
└ 變數初值設定的位置不變
└ let 和 const 沒有變數提升
console.log(a);
let a = 10;
ReferenceError: a is not defined
console.log(a);
const a = 10;
ReferenceError: a is not defined
9. 9
物件是一堆名稱與值的組合
└ 資料與行為的封裝
└ 擬人化、擬物化
└ 物件擁有紀錄資料與行為的屬性
└ 每個屬性就是一對名稱與值
└ 屬性值可以是任意 JavaScript 的值
└ 若值為函式,我們稱它為物件的方法 (method)
└ JavaScript 中所有東西都是物件
└ 不論是數字、字串、陣列、函式等等
物件
var person = {};
person.name = 'Jack';
person['age'] = 26;
var person = {
name: 'Jack',
age: 26,
friends: ['Hedy', 'Peter', 'Simen'],
parents: {
father: 'Eric’,
mother: 'Ann'
},
speak: function (text) {
console.log(text);
}
};
var person = {
name: 'Jack',
age: 26
};
13. 13
If 是條件判斷最基本的語法
└ 條件必須是 Boolean 值或運算式
└ 若是其他值,則會被自動轉型為 Boolean 值
└ 用 else if 來判斷多個條件
└ else if 數量沒有限制
└ 用 else 處理條件不符合的情況
└ 判斷式是由上到下循序執行
└ 當一個條件成立時,後面的條件不再繼續判斷
If
if (條件) {
條件為 true 時執行此程式
}
if (條件1) {
條件1為 true 時執行此程式
} else if (條件2) {
條件1不為 true,但條件2為 true 時執行此程式
} else {
條件皆不為 true 時執行此程式
}
function description(height) {
if (height < 165) {
console.log('矮');
} else if (height >= 165 && height < 175) {
console.log('平均');
} else {
console.log('高');
}
}
description(173); // '平均'
14. 14
判斷不同情況下執行不同的程式碼
└ 查對條件與標籤
└ 用 break 跳出 switch
└ 可以用 return 取代
└ 用 default 定義沒有相符的標籤時執
行的程式碼
switch
switch(條件) {
case 標籤:
如果條件 === 標籤時執行此程式
break;
default:
若沒有與條件相符的標籤時執行此程式
}
function isTodayWeekend() {
var day = new Date().getDay();
switch(day) {
case 6:
console.log('Today is Saturday’);
break;
case 0:
console.log('Today is Sunday');
break;
default:
console.log('Today is not weekend');
}
isTodayWeekend(); // 'Today is not weekend'
15. 15
while 是迴圈最基本的語法
└ 可用來創建無窮迴圈
└ do / while 在迴圈底部才判斷條件
└ 也就是說本體程式碼至少會被執行一次
└ do 迴圈結尾一定要分號
while
while (條件) {
條件為 true 時執行程式,並重複迴圈。
}
var a = 0;
while (a < 5) {
console.log(a);
a++; // a = a + 1
}
do {
執行此程式後判斷條件,若條件為 true 時重複迴圈。
} while (條件);
var b = 0;
do {
console.log(b);
b++;
} while (b < 5);
16. 16
for 迴圈經常比 while 來得便利
└ 簡化某種共通形式的迴圈
└ 初始化、條件判斷、更新
└ 任一個都可以省略
└ 但兩個分號不可省略
for
for (初始化; 條件判斷; 更新) {
條件為 true 時執行程式,並重複迴圈
}
var sum;
for (var i = 0; i < 5; i ++) {
sum = sum + i;
}
console.log(sum); // 10
19. 19
└ 套件管理系統與蓬勃發展的生態系
Node.js 生態系
Node.js Native Modules 3rd-party Modules
http stream events
buffer process …
express lodash q
async mocha …
Our Node.js Application
http … express lodash async …
npm install <module>
npm is not only a node package manager!
20. 20
基礎練習
└ (01) 用 console.log() 印出 Hello World!
└ (02) 宣告一個變數 x,並其為字串 “Hello World!”,然後印出 x
條件與迴圈
└ (03) 使用 while 迴圈印出 10 次 Hello World!
└ (04) 使用 for 迴圈印出 10 次 Hello World!
└ (05) 在 for 迴圈中,當執行第 i 次且 i 是奇數才印出 “Hello World!” (使用 if )
從 Hello World 開始
3 mins
5 mins
21. 21
你可以偷看一下
console.log('Hello World!');
var x = 'Hello World!';
console.log(x);
for (var i = 0; i < 10; i++) {
console.log('Hello World!');
}
var i = 0;
while (i < 10) {
console.log('Hello World!');
i++;
}
for (var i = 0; i < 10; i++) {
if ((i%2) !== 0)
console.log('Hello World!');
}
01
02
04
03
05
22. 22
函式
└ (06) 將打印 Hello World! 包裝成一支函式 hello(),然後呼叫它
物件
└ (07) 建立一個代表人 (person) 物件,該物件要包含有 name、gender 和 age 屬性,
並且印出 person 物件與其中的屬性 name
└ (08) 呈上,在人的物件中,加入方法 speak(),這個方法會傳入一個參數 text,並且
它會印出傳入的參數
來練習函式和物件
2 mins
5 mins
23. 23
你可以偷看一下
function hello() {
console.log('Hello World!');
}
hello();
06
var person = {
name: 'John',
gender: 'man',
age: 20
};
console.log(person);
console.log(person.name);
07
var person = {
name: 'John',
gender: 'man',
age: 20,
speak: function (text) {
console.log(text);
}
};
person.speak('Hi Hi~');
08
24. 24
Callback
└ 回呼函式、回調函式
└ 當呼叫一個函式 a 時,給他另一個函式 b;
當某種條件成立時 ,就回過頭呼叫函式 b
練習一下
└ (09) 寫一支函式 repeatHello(times, callback),然後試著呼叫它來執行 10 次 hello();這裡的
callback 應該放誰呢?
什麼是 Callback
function a (x, y, callback) {
// ... do something
callback();
}
function b () {
// I am a function
}
a('hello', 88, b);
4 mins
26. 26
建構式
└ 建立類別
└ 根據類別建立新的物件實例
└ 與 new 運算子一起使用
└ 名稱字首大寫
└ 原型:prototype
└ JavaScript 中所有物件都具有 prototype
└ Object.prototype、Array.prototype、
Function.prototype
└ 每 new 一個新的物件實例時,所有屬性都會被
new 一份出來,但原型就不會,因為是「繼承」
的概念!
建構式
Class: Person
Name
Age
Gender
Object: Peter
Name: Peter
Age: 24
Gender: men
Object: Simen
Name: Simen
Age: 36
Gender: men
Object: Hedy
Name: Hedy
Age: 23
Gender: women
function Person(name) {
this.name = name;
}
Person.prototype.hello = function () {};
var john = new Person('John');
27. 27
this
└ 會指向調用函數的物件實例
└ 在不同的場合使用它所指向的對象會不同
└ 一般函式:根據是否為嚴格模式有所差異,在稀鬆模式中
this 會參考到全域物件;在嚴格模式中 this 為 undefined
└ 建構式:this 參考到實例
└ 方法:this 參考到調用該方法的物件
this
var savedThis;
function Constr() {
savedThis = this;
}
var inst = new Constr();
console.log(savedThis === inst);
// true
var obj = {
method: function () {
console.log(this === obj);
// true
}
}
obj.method();
'use strict';
console.log(this);
// undefined
1
2
3
1
2
3
28. 28
建構式
└ (10) 建立一個 Person 建構式
└ 屬性:name, age, gender
└ 方法:hello
└ hello 方法會印出 “Hello, I am xxx.”
└ xxx 為新增實例時傳入的名字
└ 新增一個 Person 的實例
練習一下
5 mins function Person(name, gender, age) {
this.name = name;
this.gender = gender;
this.age = age;
}
Person.prototype.hello = function () {
console.log("Hello, I am " + this.name + ".");
};
var john = new Person('John', 'man', 20);
console.log(john);
john.hello();
10
29. 29
建構式
└ (11) 建立一個 Student 的建構式
└ 屬性:name, age, gender, school
└ 方法:hello, greet
└ greet 方法會印出 “Hello, I am xxx.” 和
“A student from ooo”
└ xxx 為新增實例時傳入的名字
└ ooo 為新增實例時傳入的學校
└ 新增一個 Student 的實例
練習一下
function Student(name, gender, age, school) {
this.name = name;
this.gender = gender;
this.age = age;
this.school = school;
}
Student.prototype.hello = function () {
console.log("Hello, I am " + this.name + ".");
};
Student.prototype.greet = function () {
console.log("Hello, I am " + this.name + “.");
console.log("A student from " + this.school + “.");
};
var john = new Student('John', 'man', 20, 'NTU');
console.log(john);
john.hello();
john.greet();
115 mins
30. 30
繼承另一個物件的屬性與方法
└ 實現物件原型繼承的函式 util.inherits()
└ util.inherits(A, B) 是把 B.prototype 複製到 A 身上
└ 使用 call() 繼承屬性
└ 讓父建構式用子建構式的 this 來執行初始化
└ call() 是 Function.prototype 中的方法
練習一下
└ (12) 使用 util.inherits() 讓 Student 繼承自 Person
└ 屬性:school
└ 方法:greet
重寫好麻煩:繼承
8 mins
function Student(name, school) {
Person.call(this, name);
this.school = school;
}
util.inherits(Student, Person);
var john = new Student('John', 'NTUT');
function Person(name) {
this.name = name;
}
Person.prototype.hello = function () {};
31. 31
你可以偷看一下
var util = require('util');
// Class: Person
function Person(name, gender, age) {
this.name = name;
this.gender = gender;
this.age = age;
}
Person.prototype.hello = function () {
console.log("Hello, I am " + this.name + ".");
};
// Class: Student
function Student(name, gender, age, school) {
Person.call(this, name, gender, age);
this.school = school;
}
util.inherits(Student, Person);
Student.prototype.greet = function () {
console.log("Hello, I am " + this.name + “.");
console.log("A student from " + this.school);
};
var john = new Student('John', 'man', 20, 'NTUT');
john.hello();
john.greet();
12
這個程式寫完後,請試著單獨拿掉 ,執行看看結果如何。然後,
試著單獨拿掉 再看看結果如何。如果有異狀,想想看為什麼?
引用 Node.js 原生模組 util
32. 32
模組是 Node.js 的重要支柱
└ 將程式拆分、封裝
└ 第三方模組
└ require() 載入模組
└ module.exports 公開模組介面
└ module.exports 初始值是一個物件
└ exports 也可以公開模組介面,但要注意他是
module.exports 初始值的參考
練習一下
└ (13) 讓 Person 成為一個模組,讓 Student 引用
模組系統
5 mins
var name = 'peter'
function hello() {
console.log("Hello, I am " + name + ".");
}
module.exports = hello;
var hello = require(‘./hello’);
hello();
var name = 'peter'
exports.hello = function () {
console.log("Hello, I am " + name + ".");
}
var obj = require(‘./hello’);
obj.hello();
33. 33
你可以偷看一下
// Class: Person
function Person(name, gender, age) {
this.name = name;
this.gender = gender;
this.age = age;
}
Person.prototype.hello = function () {
console.log("Hello, I am " + this.name + ".");
};
module.exports = Person;
var util = require('util');
var Person = require('./13_Person');
// Class: Student
function Student(name, gender, age, school) {
// 略
}
util.inherits(Student, Person);
Student.prototype.greet = function () {
// 略
};
var john = new Student('John', 'man', 20, 'NTU’);
console.log(john);
john.hello();
john.greet();
13
匯出 Person 建構子
匯入 Person 建構子
首先要講的是變數
在 JS 中宣告變數是有他的規則的
大駝峰是每個單字自首都大寫
剛剛前面有講到的無型別,你把數字指定給他 他就是數字 你把陣列指定給他 他就是陣列
一個 var 可以宣告多個變數,變數之間以逗號區隔
在宣告變數時,可以直接給定初值
最常用的就是 var
那在 ES6 中又加入了兩個宣告的關鍵字 let 和 const
let 和 var 很像 下一頁會詳細介紹兩者的不同
const 只要宣告後就不能再去改他 如果嘗試去修改他系統會拋出錯誤
什麼是區域變數
在這個大誇號中就是區域變數 scope 的範疇
在這個區域中,區域變數的優先序比同名稱的全域變數高
也就是當我全域變數和區域變數同時有 scope 這個變數,在這區域中我只會取得區域變數
而在這個區域外 我就只會取得全域變數
var 只有在函式中才是區域變數
let 可以在 for 區塊、if 區塊、或者是不帶任何控制目的純區塊中,使用 let 宣告區域變數
If 是 JavaScript 用來作條件判斷最基本的語法
我們可以想像一下 條件判斷其實就是我們遇到多條分岔路,然後要透過條件來選擇要走哪一條路
先看右邊第一個範例
當條件為 true 時會執行大誇號中的程式
常常 if 我們還會搭配 else if 和 else 來使用
第一個條件判斷用 if
後面的條件判斷用 else if
皆不符合的情況用 else
switch 擅長處理多路分支
在 case 後加上標籤 然後再加上一個冒號
switch 的每個 case 都表示,如果 條件 === 標籤時,就執行這段程式碼
break 會讓程式跳出 switch,如果沒有的話,程式就會繼續進到下一個 case
switch 也可以用大於小於來判斷 條件放 true 判斷式放在 case 標籤
如果沒有找到相同的值,就會改找 default 標籤
如果沒有 default 就直接跳過整塊程式碼
也可以只用 return 來結束 switch
迴圈就是讓程式自己重複執行某段程式碼
while 執行完程式後,會再回到迴圈頂端,重新判斷一次條件
do while 會先執行一次程式,才進行判斷,判斷若成立,則回到迴圈頂端
大多數的迴圈都有某種計數器,並在迴圈開始時初始化,並在每次迭代前被測試,最後在迴圈主體尾端更新
for 迴圈的主要結構 初始化 條件判斷 更新