精靈的

魔幻舞台

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)

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

註解

code 檔,不能沒有註解

// 單行註解

/*
多行註解
*/


/* 巢狀註解 /* 會 */ 爛掉 */

變數宣告

  • case-sensitive
  • 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]

常見陣列方法

陣列練習

給一篇文章,每個句子由 . 結束,將每個句子第一個字母改為大寫,其餘改為小寫。

Function 函式

應用

宣告方法一

宣告方法二

function 函數名 (參數們) {
  // 函數內容
}
var 函數名 = function (參數們) {
  // 函數內容
}
  • 頭等函數 (First-class Function):函數可以當參數丟
  • javascript 沒有 overload function:判斷 type
  • 呼叫函數時,參數數量可任意塞

任意參數

函式當參數塞

在 javascript 中,這種做法被廣泛使用

回味一下 ARRAY

取代 for 迴圈的方法

  • arr.forEach():跑過陣列所有元素(無回傳值)
  • arr.map()跑過陣列所有元素,產生新陣列(函數需回傳值)
  • arr.filter():篩掉不符合的元素

更多奇怪的方法

  • arr.every():有一個元素在測試函式 false 就回傳 false
  • arr.some()有一個元素在測試函式 true 就回傳 true
  • arr.sort():依照函式排序
  • arr.find():尋找第一個函式為 true 的元素
  • arr.findIndex():同上,找出第一個 index
  • arr.reduce():將陣列元素經由函式合併為一個元素
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 當中所有東西都有物件

  • Array()
  • Function()
  • 基本資料也有對應的建構子
    • Boolean()
    • String()
    • Number()
  • 常用的物件

練習

計算現在時間和 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

問一次不夠,有沒有問十萬次

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