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 建構子
#7:首先要講的是變數
在 JS 中宣告變數是有他的規則的
大駝峰是每個單字自首都大寫
剛剛前面有講到的無型別,你把數字指定給他 他就是數字 你把陣列指定給他 他就是陣列
一個 var 可以宣告多個變數,變數之間以逗號區隔
在宣告變數時,可以直接給定初值
最常用的就是 var
那在 ES6 中又加入了兩個宣告的關鍵字 let 和 const
let 和 var 很像 下一頁會詳細介紹兩者的不同
const 只要宣告後就不能再去改他 如果嘗試去修改他系統會拋出錯誤
#8:什麼是區域變數
在這個大誇號中就是區域變數 scope 的範疇
在這個區域中,區域變數的優先序比同名稱的全域變數高
也就是當我全域變數和區域變數同時有 scope 這個變數,在這區域中我只會取得區域變數
而在這個區域外 我就只會取得全域變數
var 只有在函式中才是區域變數
let 可以在 for 區塊、if 區塊、或者是不帶任何控制目的純區塊中,使用 let 宣告區域變數