精靈的
魔幻舞台
javascript (ES5) 核心初探
簡介
不免俗的考古一下
- 瀏覽器大戰:1995 年 Javascipt vs. 1996 年 JScript
- Ecma 國際:商用資訊及電信標準組織
- ECMA-262:標準化腳本語言--ECMAScript (1997)
- ECMAScript 的實作
- Javascript
- JScript
- TypeScript
- ActionScript ... 等等眾多「方言」
ECMAScript 的版本
- 第一版 (1997)、第二版 (1998)、第三版 (1999)
- 第四版 (ES4):廢棄
- IE 勝利,對標準制定無興趣
- Ajax 開始盛行
- 最後棄用,部分概念順延至 ES6 回鍋
- Dec 2009:第五版 (ES5)
- ES 3.1 先上,改名為 ES5
- Jun 2015:第六版 (ES6, ES2015)
- ECMAScript Harmony
- Jun 2016:第七版 (ES7)
- 主要上課內容會從 ES5 和 ES6 切入 (可能會到 ES7)
Reference: 從ES6規範看JavaScript的現在和未來
Javascipt
- 跟風取這個名字,因為當時 Java 潮到出水
- 直譯式、弱型別、動態型別語言
- javascript 部分
- ECMAScript:核心部分
- 文件物件模型 (DOM):和網頁溝通
- 瀏覽器物件模型 (BOM):和瀏覽器溝通
Javascipt 外觀
和 C++ 有 87% 像
console.log() 可以看做輸出
跑 Javascript
打開你瀏覽器的 console 就能寫了喔
Windows | Mac OS | |
---|---|---|
Chrome | Ctrl + Shift + I | Cmd + Opt + I |
Firefox | Ctrl + Shift + K | Cmd + Opt + K |
參考資料
- 參考文件:MDN
- 給學過程式的人:Speaking JavaScript: An In-Depth Guide for Programmers
- 線上練習:Codewars
基本語法
註解
code 檔,不能沒有註解
// 單行註解
/*
多行註解
*/
/* 巢狀註解 /* 會 */ 爛掉 */
變數宣告
- case-sensitive
- Unicode 字元集
- 命名規則
- 英數字、_、$
- Unicode
- 變數開頭要非數字
- ReferenceError 使用到未定義的變數或物件
var i;
var a = 2;
var tw = "台灣";
資料型態
- 基本資料型態
- 布林值 boolean:true 和 false
- 數字 number:實數
- 字串 string
- null
- undefined
- 物件 Object
- 陣列 Array
- 函式 Function
型別特性
- 動態型別
- 變數可以任意裝任何型別
-
檢查變數型別:typeof 運算子
- 弱型別
- 做運算可隱式轉換型別
true + 0
true + true
'77' - 7
Number 數字
- IEEE 754 浮點數標準
- 幾個特殊的數字
-
0、-0
-
Infinity、-Infinity
-
NaN
-
基本性質
運算子
-
算術運算子:+ - * / % ++ --
-
比較運算子:< > <= >= == != === !==
-
== vs. ===
-
-
邏輯運算子:&& || !
- 32 位元運算
-
位元運算子:& | ^ ! << >>
-
指定運算子:= += -= *= /= %= ...
String 字串
講一下基本性質
用單引號或雙引號包著
var str = '我是字串';
var str2 = "我也是";
字串建立就不可修改
取得字元
var str = 'abcd';
console.log(str[0]); // index 從 0 開始
null 和 undefined
兩個特殊的資料型態
- null 和 undefined 都有「無」的意思
- 變數沒給初始值就是 undefined
- 函式沒回傳值就回傳 undefined
- null 對抗 undefined
typeof null // bug in ECMAScript
typeof undefined
null === undefined
null == undefined
NaN 參戰,你確定你的武器夠嗎?
NaN === NaN;
Number.NaN === NaN;
isNaN(NaN);
isNaN(Number.NaN);
檢查 NaN:isNaN()函式
控制結構
// if 結構
if (child === '狂') {
result = '開噴';
}
// if-else 結構
if (child === '神亦') {
result = '1600 萬台戰';
}
else {
result = '單機遊戲';
}
// if-elseif 結構
if (door !== '打開') {
result = '沒事';
}
else if (husband === '睡在床上') {
door = '關起來';
result = '假的!';
}
else {
eye = '業障重';
}
迴圈結構
while 敘述
/*
while 敘述
若 rich 是 true
則輸出 '一直丸'
*/
while (rich === true) {
console.log('一直丸');
}
for 敘述
console.log('讓我們默哀 10 秒');
/*
for 敘述
用迴圈計數
*/
for (var i = 1; i <= 10; i++) {
console.log(i);
}
-
break
-
continue
-
do ... while
語法練習
- 判斷平年閏年
String 字串
基本功能介紹
字串串接
-
+ 運算子
- 奇怪的特性
"3" + 1
"3" - 1
"3" - -"1"
字串方法
參考:字串所有方法
字串數字互相轉換
字串練習
給一個英文句子,請把句子第一個字母變大寫,其餘變小寫
Array 陣列
概觀
-
用中括號 [] 包著 , 隔開元素
- 可以放各式各樣型態的資料
-
陣列長度 arr.length
陣列,我那麼相信你 R!
[] == ''
[''] == ''
[] == ['']
[] == []
[] == ![]
判斷陣列:Array.isArray()
typeof [1, 2, 3]
常見陣列方法
-
加入元素:arr.push(元素1, ...)
-
刪除元素:arr.pop()
-
串接元素:arr.join(separator)
-
合併陣列:arr.concat(陣列1, ...)
-
取子陣列:arr.slice(start, end)
-
拔掉第一個元素:arr.shift()
參考:所有陣列方法
陣列練習
給一篇文章,每個句子由 . 結束,將每個句子第一個字母改為大寫,其餘改為小寫。
str.split(separator)
Function 函式
應用
宣告方法一
宣告方法二
function 函數名 (參數們) {
// 函數內容
}
var 函數名 = function (參數們) {
// 函數內容
}
- 頭等函數 (First-class Function):函數可以當參數丟
- javascript 沒有 overload function:判斷 type
- 呼叫函數時,參數數量可任意塞
任意參數
函式當參數塞
在 javascript 中,這種做法被廣泛使用
回味一下 ARRAY
取代 for 迴圈的方法
更多奇怪的方法
arr.reduce(function(prev, num) {
return prev + num
})
陣列元素加總
練習
建質數表
開根號:Math.sqrt()
練習
合併排序法 (遞迴)
Object 物件
概觀
- 鍵值對 (Key-Value pair)
- 一個 key 會對到一個值
var 透天厝 = {};
透天厝['一樓'] = '店面';
透天厝['二樓'] = '住家';
透天厝['頂樓'] = '不加蓋';
console.log(透天厝);
var 透天厝 = {
一樓: '店面',
二樓: '住家',
頂樓: '不加蓋'
};
console.log(透天厝);
- 物件內每個 key 值叫做「屬性 (attribute)」
- 若成員是函式,則稱為「方法 (method)」
var 透天厝 = {};
透天厝.一樓 = '店面';
透天厝.二樓 = '住家';
透天厝.頂樓 = '不加蓋';
console.log(透天厝);
方法 METHOD
THIS
可以用this來獲得物件的屬性
Pass by reference
- 物件作為傳遞參數時,是傳 reference
- 基本資料型態是 pass by value
物件比較
- 比較 reference 是否相同
- 因為是 pass by reference
- 有沒有辦法知道,物件內的屬性值是否相同?
- Ans: 目前沒有直接的方法檢查
// 測試看看
console.log({} === {})
// 試試看
var a = {};
var b = a;
console.log(b === a)
b.xd = 1;
console.log(a);
自訂物件
建構子 Constructor
建立物件的函式
// 建構子
function Circle(x) {
this.radius = x; // 用 this 指派屬性值
this.area = function area() { // 設定方法
return this.radius * this.radius * 3.14;
}
}
var c1 = new Circle(3); // 半徑為 3 的圓
var c2 = new Circle(0xC8763); // 半徑為 0xC8763 的圓
c1.area();
c2.area();
Prototype
共用某些性質,減少浪費記憶體
所有函式都有 prototype
萬物皆物件
javascript 當中所有東西都有物件
練習
計算現在時間和 2000/1/1 之間有幾秒
注意函式和建構子的差異
array 性質
出場第三次~
- javascript Array 是物件模擬陣列操作
- 可以做奇怪的事情
in 敘述
檢查 key 值是否有在物件內
var obj = {
scientist: '鳳凰院',
assistant: 'Christina'
}
0 in obj; // false
'scientist' in obj; // true
// array 事實上是物件模擬
var arr = [4, 2, 6]
arr['XD'] = '哈哈你找不到我';
2 in arr; // true, index 2
4 in arr; // false
'XD' in arr; // true
for ... in 敘述:遍歷物件的 key
var arr = [4, 2, 6]
arr['XD'] = '哈哈你找不到我';
for (var i in arr) {
console.log(i); // 0, 1, 2, XD
}
難度G也要全部超越
ギリギリ愛~ギリギリ舞~
Truthy & Falsy
Truthy 陣營
Falsy 陣營
-
true
- 非 0
- 非空字串
- {} (所有物件)
- []
-
false
- 0
- 空字串
- null
- undefined
- NaN
但這不是 true 跟 false!
舉例
[] == true // false
[] == false // true
if ([]) {
console.log('QQ');
}
else {
console.log('XD');
}
閉包 (Closure) 和作用域 (Scoping)
This 之亂
prototype
wtfjs 很好用
還有一個但是作者進不去
世上最遙遠的距離
Number.MAX_VALUE*1.0000000000000001 === (1/0) // false
Number.MAX_VALUE*1.0000000000000002 === (1/0) // true
- 不是我跟你
- 而是 Infinity 在你面前
- MAX_VALUE 卻不是 Infinity
陣列數數
要相信你手中的 javascript
[] == 0 // true
+[] === 0 // true
++[] === 0 // ReferenceError
[[]][0] === 0 // true
++[[]][0] === 1 // true, wtf
++[[]][+[]] === 1 // true, yay
- 可以從 0 數到 1000 喔!
- js 真奇妙,就看你有沒有注意到
問一次不夠,有沒有問十萬次
Chrome 瀏覽器 JIT bug
console.log(typeof null == 'undefined'); // false
for (var i = 0; i < 100000; i++)
console.log(typeof null == 'undefined'); // wtf
發問時間
可能都一頭霧水了 ......
END
精靈的魔幻舞台:javascript 核心初探
By Hsu Heng Yu
精靈的魔幻舞台:javascript 核心初探
2016 板中資訊社暑期課程 (4) CC-BY-NC-SA 4.0 by 許恆與 (a.k.a. m80126colin)
- 199