JavaScript 說明
基本
ECMA-262是定義了Javascript的核心規範
註解 and Hello World
1 | // This is a comment |
import module
1 | // require |
require() vs import()
require() 是 node.js 內含函數
require() 執行 然後 return
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17var myVar = require('http') //to use built-in modules
var myVar2 = require('./myLocaModule') // to use local modules
// example for require - demo_module.js
var http = require('http');
var dt = require('./myfirstmodule');
// 'Content-Type': 'text/html;charset=utf-8' 修正中文亂碼
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/html;charset=utf-8'});
res.write("The date and time are currently: " + dt.myDateTime());
res.end();
}).listen(8080);
// myfirstmodule.js
exports.myDateTime = function () {
return Date();
};import()/export() 為 ES6 新語法, 若含.json 文件類型則不能使用
<script> type=”module” 也不能使用
require() 可擺於任何地方,import() 擺於程式最前面
1
2
3
4
5
6
7
8
9
10
11var myVac = import("module-name");
// example for import
// app.js
import {add, PI} from './utils.js'
console.log(add(3, 5), PI) // 8 3.14
// utils.js
export function add(a, b) {
return a + b
}
export const PI = 3.14
Hoisting (提升)
example
1 | // not defined |
原理
EC(Execution Contexts)
VO(variable object)
AO(activation object)
Closure (閉包)
example
1 | // example #1 |
Closure 造成問題
1 | // closure trigger issue |
Closure(閉包) 應用 - 隱藏資訊
1 | function createWallet(init) { |
物件導向(Object Oriented Programming) and prototype
ES6 class
1 | class Dog { |
ES5
1 | // example #1 - 會產生重複相同之 function |
prototype 原型鍊
Example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.log = function () {
console.log(this.name + ', age:' + this.age);
}
var nick = new Person('nick', 18);
var peter = new Person('peter', 20);
nick.log();
console.log(nick.log === peter.log) // true
// nick.__proto__ 指至 Person.prototype
console.log(nick.__proto__ === Person.prototype) // true
// Person.prototype.__proto__ 指至 Object.prototype
console.log(Person.prototype.__proto__ === Object.prototype) // true
// Object.prototype.__proto__ === null (到頂端)
console.log(Object.prototype.__proto__) // null
// Person.__proto__ 指至 Function.prototype
console.log(Person.__proto__ === Function.prototype); // true
console.log(Function.prototype.__proto__ === Object.prototype) // true
console.log(Object.prototype.__proto__); //null.hasOwnProperty() 判斷自身屬性是否存在
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33function Person(name, age) {
this.name = name;
this.age = age;
}
// Person.prototype add function log
Person.prototype.log = function () {
console.log(this.name + ', age:' + this.age);
}
var nick = new Person('nick', 18);
// hasOwnProperty() 檢查是否直屬屬性
console.log(nick.hasOwnProperty('log')) // false
console.log(nick.__proto__.hasOwnProperty('log')) // true
console.log(Person.prototype.hasOwnProperty('log')) // true
// Object.prototype add function testObject()
Object.prototype.testObject = function() {
console.log("Object :", 999)
}
// test call Object.prototype function
nick.testObject() // Object : 999
// list all property
for (let key in nick) {
if (nick.hasOwnProperty(key)) {
console.log(`Property ${key}: ${nick[key]}`)
}
else {
console.log(key);
}
}
// Property name: nick
// Property age: 18
// log
// testObjectinstanceof 就是拿來判斷 A 是不是 B 的 instance
1
2
3
4
5
6
7
8
9
10
11
12
13
14function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.log = function () {
console.log(this.name + ', age:' + this.age);
}
var nick = new Person('nick', 18);
console.log(nick instanceof Person); // true
console.log(nick instanceof Object); // true
console.log(nick instanceof Array); // false
new 程序模擬
1 | function Person(name, age) { |
繼承 Inheritance
1 | class Dog { |
this
1 | // 無用的 this 列出環境變數, node.js 和 web browser 會有差異 |
call, apply and bind(可更改 this 值)
apply 參數為 array 輸入
bind 能預設 this 及 一些 參數
1 |
|
1 | // apply |
箭頭函式中,this 指稱的對象在所定義時就固定了,而不會隨著使用時的脈絡而改變
1 | // 使用 匿名函式 |
try…catch 陳述式
1 | try { |
throw
1 | // 拋出例外 |
變數 variable
var, let and const
1 | // let and const 是在 ES6 才使用 |
data structures - 資料型別與資料結構
種類
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53// --- Primitive ( immutable value - 不可變)
// Boolean
// Null
// Undefined
// Number(數字)
// BigInt(這是一個實驗中的功能) : BigInt 是透過在一個數值後加上 n 或呼叫 BigInt()
// String(字串)
// Symbol(於 ECMAScript 6 新定義)
// ---
// Object (物件) - immutable value : array, function, date ...
// --- dump type
console.log(typeof true) // boolean
console.log(typeof null) // object
console.log(typeof undefined) // undefined
console.log(typeof 1234567) // number
console.log(typeof 12n) // bigint
console.log(typeof 'Hello World!') // string
console.log(typeof Symbol()) // symbol
console.log(typeof { name: 'Jack' })// object
console.log(typeof [1, 2, 3]) // object
console.log(typeof function() {}) // function
console.log(typeof NaN) // number, NaN(not a number)
// check array
console.log(Array.isArray([])) // True
// check NaN(唯一 自己不等於自己)
let num = Number("hello")
console.log(num) // NaN
console.log(num === NaN) // false
console.log(num === num) // false
console.log(typeof num) // number
// check undefined
let a
console.log(a) // undefined - 型態
console.log(typeof a) // undefined - 字串
// check undefined 再處理
let b
if ( typeof a !== 'undefined') {
console.log("undefined", b+1) // undefined NaN
}
else {
console.log(b+1)
}
// check NaN
let num = Number("hello")
console.log(num, typeof num) // NaN number
console.log(num === NaN) // false
console.log(isNaN(num)) // true
// 檢視物件到底是屬於哪個子型別 Object.prototype.toString
console.log(Object.prototype.toString.call([1, 2, 3])) // "[object Array]"
console.log(Object.prototype.toString.call({ name: 'Jack' })) // "[object Object]"
console.log(Object.prototype.toString.call(function sayHi() {}))// "[object Function]"
console.log(Object.prototype.toString.call(/helloworld/i)) // "[object RegExp]"
console.log(Object.prototype.toString.call(new Date())) // "[object Date]"exampe
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35// NaN : Not-A-Number
var age = 20
// 區域變數
let temp = 10
// variable undifined
var total
console.log(total)
// variable not difined
console.log(money)
// varibale 型態
// bollean, number, string
// object, undefined, function
console.log('type true', typeof true)
console.log('type 30', typeof 30)
console.log('type 0.5', typeof 0.5)
console.log('type "hello"', typeof 'hello')
console.log('type "30"', typeof '30')
console.log('type [1]', typeof [1])
console.log('type {a:1}', typeof {a:1})
console.log('type null', typeof null)
console.log('type underined', typeof underined)
console.log('type function', typeof function(){})
// result
type true boolean
type 30 number
type 0.5 number
type "hello" string
type "30" string
type [1] object
type {a:1} object
type null object // It's more special
type underined undefined
type function function
number
1 | // 最大整數 2^53 - 1 : Number.MAX_SAFE_INTEGER |
String
1 | // ascii code 和 字元 互轉 |
陣列 Array
1 | var scores = [ 30, 70, 60, 50] |
array item remove
1 | // 使用 delete array 會造成 length 不變, 原來的值變成 undefined |
array 合併
1 | const array1 = ['a', 'b', 'c']; |
物件 object
example
1 | var person = { |
運算式與運算子
== 與 === (=== 也比較型態,建議全用 ===)
1 | console.log("0=='0'", 0=='0') |
邏輯運算子
1 | # 定義 |
算術運算子
1 | # 定義 |
2**3 : $2^3$
位元運算子
1 | a & b : 位元 AND |
條件式
if 條件式
1 | var score = 85 |
switch case
1 | var month = 2 |
三元運算子 Ternary
1 | console.log( 10 > 5 ? 'bigger' : 'smaller') |
迴圈
兩種改變迴圈的指令 : break, continue
for 迴圈
1 | for (let i=0 ; i<10 ; i++) { |
for in
ES5標準,遍歷的是key
1 | let arr = ['a','b','c','d',{'e':'e_value','f':'f_value'}] |
for of
ES6標準,遍歷的是value
可使用的對象有Array、Map、Set、String、TypedArray、arguments
1 | let arr = ['a','b','c','d',{'e':'e_value','f':'f_value'}] |
while 迴圈
1 | // while |
函式
基本型式
1 | function multiply(num1,num2) { |
函式含 callback function
1 | let arr = [1, 2, 3] |
匿名數式 anonymous function
1 | let arr = [1, 2, 3] |
箭頭函式 arrow function
1 | // 只有一個參數時,括號才能不加: |
參數(Parameter)與引數(Argument)
1 | // a,b 參數(Parameter) |
內建函式
Math
1 | // 亂數 介於0到1之間(包含 0,不包含1) |
Array
map
1 | // 簡單型式 |
indexOf/lastIndexOf
1 | // 第一個找到之索引, 不存在傳回 -1 |
join
1 | // 用某字串結合array成字串 |
filter
1 | // filter 陣列內容設定條件成立即留下 |
slice
1 | // 切下某些 array 內容 |
splice (改變原陣列)
1 | // array.splice(start[, deleteCount[, item1[, item2[, ...]]]]) |
sort (改變原陣列)
1 | // 文字排序 |
reverse (改變原陣列)
1 | const array1 = ['one', 'two', 'three']; |
some - 來檢查陣列裡面是否有一些符合條件。只要有一個以上符合條件就會回傳 true
1 |
|
every - 陣列裡面的所有東西都符合條件才會回傳 true
JSON
1 | // JSON.stringify() - method converts a JavaScript value to a JSON string |
Global
encodeURIComponent()/encodeURI() - encode a URI
1 | var uri = "my test.asp?name=ståle&car=saab"; |
decodeURIComponent()/decodeURI() - decode a URI
1 | var uri = "my test.asp?name=ståle&car=saab"; |
ES6
ECMAScript ECMA-262 6th edition-June 2015, 所以稱為 ES6 或 ES2015
let 和 const
var 的 scope(作用域) 是 function
let, const 的 scope(作用域) 是 block
const 為常數,執行中不可更改
Template Literals (字串樣版)
使用兩個反引號 (back-tick ) ‵ ‵ 標示
多行字串
1 | // SE5 |
嵌入變數
1 | var name = 'Robert' |
Destructuring (解構)
1 | // array |
Spread Operator (展開) - 可用於複製 array 或 object 內容
1 | // array |
Rest Parameters (剩餘參數) - 不一定用 rest 可用其他變數名稱
1 | // array - 不一定用 rest |
Default Parameters (預設值)
1 | function repeat(str='hello', times = 5) { |
Arrow Function (箭頭函式)
1 | const test = (n) => { |
import and export
ES5
1 | // utils.js |
1 | // test1.js |
1 | $ node test1.js |
ES6
Export 有幾種方式:
- export function add(){},使用 import {add} 引入
- export { add },與上面那種一樣
- export default function add(),使用 import add 引入,不需要加大括號
如果想要用其他名字,可以用 as 取別名,例如說 export { add as addFunction }
可以用 import * as utils from ‘utils’ 把全部都 import 進來
使用 import package.json 要加 “type”: “module”
1 | { |
1 | // utils.js #1 |
1 | // test1.js #1 |
API
console
1 | // normal |
process.stdout.write - 不換行列印
1 | process.stdout.write('This is ') |
JS庫
- Modernizr : 一個開源的JS庫,它使得那些基於訪客瀏覽器的不同(指對新標準支援性的差異)而開發不同級別體驗的設計師的工作變得更為簡單
應用
require(‘readline’) 用於自動測試
Code - test.js
1 | var readline = require('readline'); |
input file - input.txt
1 | 10 13 |
執行
1 | $ cat input.txt | node test.js |
NPSC 測試
1 | cat pa.in | node code.js | diff pa.out - |