2019年3月31日 星期日

[Back To Basic] Javascript - Object

在 javascript 中,除了 Primitive 以外,其他都是 Object。

Primitive

是不可變(Immutable)的。

Object Method

  • object method 也是 object property
  • 包含 function definition

建立 Object

建立 Object 有數種方式
  • Object Literal(建議用法)
var user = { name: 'Shawn', age: 18 };
  • 關鍵字 new
var user2 = Object();
user2.name = 'Shawn';
user2.age = 18;

物件(Object)是可變的(Mutable)

物件是可變的,是傳址(by reference)的概念


2019年3月27日 星期三

[Back To Basic] Javascript - JSON

JSON(JavaScript Object Notation)

  • 一種儲存/傳輸的資料格式
  • 通常用於往返 client 和 server
  • 是一個獨立的語言
  • 輕便的資料交換格式
  • 語法從 javascript 的 object 延伸而成
  • 很容易和 javascript 的 object 相互轉換

JSON語法

  • 一個資料名稱 對應 一個資料值
  • 用逗號分隔
  • {} 表示物件(object)
  • []  表示陣列(array)
  • 資料名稱必須用雙引號框住, javascript的 object 不用
{
"member":[

  {
    "name": "Shawn",
    "age": 18
  },
  {
    "name": "Koji",
    "age": 22
  }
]}

[Back To Basic] Javascript - ES6

ES6 = ECMAScript 6 = ECMAScript 2015


// 設定 y 的預設值
function count(x, y = 5) {
    return x + y;
}
  • Array.find()
  • Array.findIndex()
  • 新增常數
    • Number.EPSILON
    • Number.MIN_SAFE_INTEGER
    • Number.MAX_SAFE_INTEGER
  • Number.isInteger()
  • Number.isSafeInteger()
安全的數值介於 -(2^53 - 1) ~ (2^53 - 1) 之間
  • isFinite()
是否為有限數值
  • isNaN()
是否不是數值

Arrow Functions

新語法: const myFunction = (x, y) =>  x + y ;
可取代:
function(x , y) {
  return x + y;
}
特性
  • arrow function 沒有自己的 this
  • 不適合用來定義object的method
  • arrow function 不會 hoisting
  • 建議使用 const,因為 arrow function 通常定義後就不會改變
  • 建議保持大括號和 return,因為大括號和保留字只有一行陳述式可省略
 const myFunction = (x, y) =>  { return x + y };

2019年3月25日 星期一

[Back To Basic] Javascript - ES5

ES5 = ECMAScript 5 = ECMAScript 2009,IE9以上皆支援。

這份規範中的語法:

  • String.trim()
字串的空白去除
  • JSON.stringify()
將 json 格式轉成字串,通常用於傳輸到後端前的格式轉換。
  • Date.now()
取得從1970/1/1 00:00:00 UTC 到當下的毫秒數
  • Getter 和 Setter
  • 物件多了很多方法,其中Object.defineProperty()
    • 定義屬性
    • 修改屬性值
    • 修改中繼資料
  • charAt()
取回字串的某個字元
  • 允許多餘的逗號在物件或陣列中
    • IE8會壞掉
  • 字串可藉由反斜線符號( \ ),多行撰寫
    • 舊瀏覽器(IE8以前)可能會異常
"Hello \
World";



2019年3月24日 星期日

[Back To Basic] Javascript - 效能(performance)

  • 減少迴圈陳述式的計算
// 不要在 for 迴圈的陳述式中取長度(每跑一次都會訪問一次陣列)
// for (let i = 0; i < array.length; i++) { }

// 事先取得長度
var arrayCount = array.length;
for (let i = 0; i < arrayCount; i++) { }
  • 減少DOM的訪問
// 每次訪問demo1都使用這個變數,取代一直訪問DOM
var demo1 = document.getElementById('demo1');
demo1.innerHTML = 'Hi';
  • 降低DOM的大小
盡量減少 HTML的元素,在
    • 頁面載入
    • 重新渲染(re-render)
    • 訪問DOM
這些情境都能增進效能
  • 減少不必要的變數
  • 將 javascript 檔案放在頁面最下方載入
  • 避免使用 with

2019年3月21日 星期四

[Back To Basic] Javascript - 最佳實例

避免全域變數(global variables)

  • 最少化全域變數
  • 盡量使用區域變數(local variables)
  • 使用閉包(closure)

宣告放到最上方

初始化變數(一開始就給定預設值)

避免宣告

  • Number
  • String
  • Boolean

使用特定語法(看source code)

注意自動轉型的可能

使用 === 取代 ==

因為 == 在運算的時候會自動轉型

將function的參數給定預設值

使用 switch 時,最後都加上 default 宣告

不要使用 eval()

2019年3月20日 星期三

[Back To Basic] Javascript - 風格指南(style guide)

目的為確保程式的品質

  • 可讀性
  • 可維護性

變數名稱

  • 使用小駝峰命名法(camelCase)
  • 所有變數以字母(letter)開頭

操作符號(operators)和逗號(comma)

  • 操作符號左右空一格
  • 逗號後方空一格

縮排(Identation)

  • 在區塊(block)中使用二個空格縮排

簡單Statement規則

  • 一個陳述結束要用分號(;)結尾

區塊Statement規則

  • 開頭括號在第一行結尾後方
  • 開頭括號前給一個空格
  • 結尾括號放在新的一行, 後方不要有空白
  • 結尾括號後面不用加上分號

物件(Object)規則

  • 開頭括號在第一行結尾後方
  • 屬性名稱和值中間加上冒號和一個空白
  • 屬性值若是字串加上引號在兩旁, 若是數值則不要加
  • 最後一個屬性值組合後面不要加上逗號
  • 結尾括號放在新的一行, 後方不要有空白
  • 結尾括號後面要加上分號, 作為物件定義的結束

單一行程式碼長度

  • 不要超過80個字元

載入外部 script 時不要加入 type 宣告

副檔名用 .html 不要用 .htm

檔名都用小寫,因為有些伺服器會將大小寫視為不同檔案

小的 script檔案以可讀性為目標,大的 script 檔案以壓縮到最小為目標

2019年3月19日 星期二

[Back To Basic] Javascript - Const

用 const 宣告的變數擁有 let 所有特性,外加一個特性: 不可被重新設值
基於外加的特性,用 const 必須在宣告的時候設值

  • 正確用法

const PI = 3.14;

  • 錯誤用法

const PI;
PI = 3.14; // 不可重新設值

注意

用 const 宣告的變數,它的屬性(property)還是可以改寫。
  • 物件(object)
const employee = { name: 'Shawn', dept: 'MKPL', age: 18 };
employee.name = 'Ray'; // 可以改寫屬性

employee = { name: 'Ray', dept: 'MKPL', age: 28 }; // 不可重新設值
  • 陣列(array)
const fruits = ['Apple', 'Banana'];
fruits.push('Watermelon'); // 可以改寫屬性

fruits = ['Apple', 'Banana', 'Watermelon'];  // 不可重新設值

瀏覽器支援: IE10以前不支援 const

2019年3月18日 星期一

[Back To Basic] Javascript - Let

在ECMAScript 2015出來之前,變數的 Scope 只有二種:
  • global Scope
  • local Scope / function scope
之後有了第三種:
  • Block Scope
在大括號中使用 let 宣告的變數,外面不可使用。
{
  let name = 'Shawn';
}
// name 不可在這使用

解決了什麼問題

  • 重新宣告的問題
var name = 'Ray';
{
  var name = 'Shawn';
}
// name 在這邊會變成Shawn
------------------------------------------

var name = 'Ray';
{
  let name = 'Shawn';
}
// name 在這邊會保持原本的Ray
  • Hoisting的問題
用 let 必須先宣告才能使用

瀏覽器支援: IE11以前不支援 let

2019年3月17日 星期日

[Back To Basic] Javascript - this

javascript 的 this 代表的是: 某個屬性(property)隸屬的物件(object),也就是說 this 的值不固定。

this代表的是誰?

  • 物件(object)中的方法(method)的this
var user = {
    name: 'Shawn',
    getUser: function () {
        return this; // this 代表 user,因為 user 擁有 getUser()
    }
}
  • 單獨使用this (嚴格模式的結果也一樣)
var temp = this; // this 代表全域物件(global object),瀏覽器中的全域物件是 window
  • 在 function 中使用this
function myFunction(){
  return this; // this代表全域物件(global object),因為這個function隸屬於全域物件(global object)
}
  • 在 function 中使用this (嚴格模式)
"use strict";
function myFunction(){
  return this; // this的值為undefined,嚴格模式中,不允許預設綁定
}
  • 在事件處理(event handler)上使用this
<!-- this代表整個 button HTML元素 -->
<button onclick="onClick(this)">Click</button> 

預設的javascript method

javascript會預設一些method在function中
  • call()
  • apply()
  • ...

2019年3月14日 星期四

[Back To Basic] Javascript - 嚴格模式(strict)

若使用 "use strict";
  • 定義這份javascript的程式碼要用嚴格模式執行
  • ECMA Script 5 的directive
  • IE9以後皆支援,IE9以前皆忽略
  • 只是一串字串,並不是語法,所以舊版本的瀏覽器不會出錯
  • 可以幫助我們寫出更乾淨的程式碼
  • 必須宣告在script的最前面
  • 全域影響整份script

使用嚴格模式的好處

  • 幫助我們寫出更安全的程式碼
  • 將以前接受的錯誤語法更改為實際錯誤

在嚴格模式中不被允許的寫法

  • 使用沒有宣告的變數
x = 31;
user = {name: 'Shawn', age: 18}; // object也是變數,必須宣告
  • 刪除變數
var pi = 3.14;
delete pi;

function myFunction(a, b){ }
delete myFunction;
  • 參數名稱重複
function(a, a){ }
  • 不允許8進位數字文字
var x = 010;
  • 不允許8進位轉義字符
var x = "\010";
  • 不允許唯讀的屬性被寫入
var constantCollection = {};
Object.defineProperty(constantCollection, "pi", { value: 3.14, writable: false });
constantCollection.pi = 3.14159;
  • 不允許 get only 的屬性被寫入
var obj = {
    get x() {
        return 0
    }
};
obj.x = 3.14;
  • eval 不可用來當變數
var eval = 0;
  • arguments 不可用來當變數
var arguments = 0;
  • 禁止使用with語法
with (Math) { x = sin(2) };
  • 禁止使用eval() 函式
eval("var name = 'Shawn'");
  • 保留字也別用來當變數

2019年3月13日 星期三

[Back To Basic] Javascript - Hoisting

Hoisting是一種javascript的語言特性,javascript會把宣告移到當下的scope的最上方。
也就是說

  • 可以在使用變數後才宣告
  • 變數可以在宣告前使用

let 和 const

使用這2種宣告方式,就不會發生 hoisting。

只有宣告會 Hoisting,初始值不會 Hoisting

e.g.
console.log(age); // age = undefined
var age = 18;

Note

務必宣告所有變數在所屬的Scope的最上方,避免不知道的人製造bug

使用嚴格模式就可以,不允許變數在宣告前使用(取消hoisting的特性)

2019年3月12日 星期二

[Back To Basic] Javascript - 作用域(Scope)

javascript中有2種作用域(scope)
  • local scope / function scope
每個function都會建立一個作用域(scope),在function之內宣告的變數,外面看不到,也不可訪問/使用。
  • global scope
作用域(scope),會決定

  • 可見性(visibility)
  • 可訪問性(accessibility)

區域變數(Local Variables)

  • 宣告在function中的變數,只有在該function中可見、可訪問
  • 區域變數,在function開始時建立,function結束時移除
function myFunction1() {
    var userName = 'Shawn';
    // userName = 'Shawn'
}
    // userName undefined

全域變數(Global Variables)

  • 宣告在function外的變數,就是全域變數
  • 在網頁中的所有script和function都可見、可訪問
var userDept = 'Marketplace';
function myFunction2() {
    //  userDept = 'Marketplace'
}
    //  userDept = 'Marketplace'

變數(Variables)

在javascript中,object 和 function 也是變數(variables)。
所以object 和 function 的可見性、可訪問性也是遵循作用域(scope)的規則。

自動判定為全域變數(Automatically Global)

若在function中的變數沒有宣告,則自動變成全域。
function myFunction3() {
    sex = 'male';
    // sex = 'male';
}
// sex = 'male'

嚴格模式(Strict mode)

為了避免自動判定為全域變數(Automatically Global)的問題,可以使用嚴格模式(Strict mode),在嚴格模式中,變數不會被自動視為全域。

全域變數在HTML中(Global Variables in HTML)

所有的全域變數,都會自動存在window物件底下。

var birthday = '1/1';
window.birthday; // 1/1

盡量避免使用全域變數,因為可以蓋來蓋去

javascript變數的生命週期

  • 變數的生命起始於宣告。
  • 區域變數在function結束時中止。
  • 全域變數在瀏覽器關閉或瀏覽器頁面關閉時終止。
  • function的參數視為區域變數。

2019年3月11日 星期一

[Back To Basic] Javascript - Errors

javascript例外處理由下列語法組成
  • try
    • 被測試的程式碼區塊
  • catch
    • 處理例外
  • throw
    • 建立自定義例外
  • finally
    • 在try catch後要執行的程式碼區塊

例外發生

try {
  // 被測試的程式碼
}
catch(err) {
  // 發生例外時執行的程式碼
} finally {
  // 不管有沒有發生例外,都會執行的程式碼
}

throw

可以丟(throw)出四種型別
  • String
  • Number
  • Boolean
  • Object
 try {
  //  拋出例外
  throw "whatever you want";
}
catch(err) {
  // err = "whatever you want"
}

Error Object

javascript提供錯誤物件,包含兩個屬性(property)
  • name
    • 錯誤名稱
  • message
    • 錯誤訊息

常見的錯誤如下

  • RangeError
    • 數值超出合法範圍
  • ReferenceError
    • 變數還沒被宣告
  • SyntaxError
    • 語法錯誤
  • TypeError
    • 型別錯誤
  • URIError
    • 在URI (Uniform Resource Identifier)中使用不合法的字元

2019年3月10日 星期日

[Back To Basic] Javascript - 正則表達式(reqular expression)

正則表達式是用一串符號,用來確認文字的格式,常被用於
  • 搜尋
  • 取代
  • 比對

語法

/pattern/modifiers

pattern 和 modifiers 說明如下:

pattern

  • 括號 - 尋找特定範圍的符號
    • [0-9]
    • [a-z]
    • [A-Z]
    • (a | b)
      • 比對a或b
  • 具有特殊意義的元字符(Metacharacters)
    • \d
      • 尋找數字
    • \s
      • 尋找空白字元
    • \b
      • 尋找文字的開頭或結尾(英文)
        • e.g. /\bSh/ 尋找Sh開頭或結尾的文字
    • \uxxxx
      • 用16進制的數字(xxxx),尋找指定的字元
  • 量詞(Quantifiers)
    • n+
      • 最少一個n
    • n*
      • 0到多個n
    • n?
      • 0或1個n

modifiers

  • i
    • ignoreCase
    • 忽略大小寫
  • g
    • global
    • 全域比對
  • m
    • multiline
    • 多行比對

RegExp物件(RegExp object)

  • pattern.test("test String")
    • 比對一串字串是否符合正則表達式
  • pattern.exec("test String")
    • 針對一串字串執行正則表達式
常見應用 email格式驗證 source code

[Back To Basic] Javascript - 位元運算(Bitwise)

位元運算的方式,在程式語言中,是非常貼近硬體的計算方式,效能會較好,但是javascript沒有這種特性。

位元運算(Bitwise)

  • 儲存成 64bits
  • 計算時轉換成 32bits,算完轉回 64bits

2019年3月7日 星期四

[Back To Basic] Javascript - 型別轉換(Type Conversions)

型別

Javascript的型別
  • 可存值
    • string
    • number
    • boolean
    • object
Javascript有6種物件
      • Object
      • Date
      • Array
      • String
      • Number
      • Boolean
    • function
  • 不可存值
    • null
    • undefined

typeof

可用來取得變數的型別。結果超出預期的如下

type of NaN; // number
type of new Array(); // object
type of new Date(); // object
type of null; // object
type of undefined; // undefined

  • 由上述可知,typeof 難以辨別和 object 相關的型別或特殊的型別。
  • typeof 本身是一種符號,類似於 + - * / 的角色,因此 typeof 本身沒有型別

取得變數的建構式

為了解決 typeof Array, typeof Date, typeof null 都是object 的問題,首先觀察constructor。
  • 是不是Array
function isArray1(v) {
    return v.constructor.toString().indexOf('Array') > -1;
};

function isArray2(v) {
    return v.constructor === Array;
}
  • 是不是Date
function isDate1(v) {
    return v.constructor.toString().indexOf('Date') > -1;
};

function isDate2(v) {
    return v.constructor === Date;
}

型別轉換

2種型別轉換方式
  • 使用javascript提供的function
    • 轉成字串
      • String(var)
      • var.toString()
    • 轉成數值
      • Number(var)
        • Number(""); // 回傳 0
        • Number(true); // 1
        • Number(false); // 0
      • +
        • e.g. var num = + "13"; // num = 13;
        • e.g. var num = + "Shawn"; // num = NaN;
    • javascript自動轉換型別


2019年3月6日 星期三

[Back To Basic] Javascript - break 和 continue

  • break
跳出迴圈
  • continue
跳過一次迴圈

標籤功能(JavaScript Labels)

break 和 continue 可以配合標籤功能,可以跳脫指定的迴圈。
常常使用在需要一次跳出巢狀迴圈的情境。

  • label語法
label:
statement
  • break [label];
  • continue [label];
example:

[Back To Basic] Javascript - while 迴圈(while loop)

二種while迴圈

  • while
最常見的while迴圈


while (condition) {
  // logic
}

  • do / while
第一次執行不看條件,一定會執行一次


do {
  // logic
} while (condition);

for迴圈和while迴圈的比較

二者功能相同,for迴圈的某些陳述式省略就和while長得很像

[Back To Basic] Javascript - for 迴圈(for loop)

二種for迴圈:

  • for
最常見的迴圈語法。


for (statement 1; statement 2; statement 3) {
  // logic
}

  • for / in
主要功能在處理物件的屬性。

for (const objectProperty in object) {
  // logic
}

2019年3月5日 星期二

[Back To Basic] Javascript - Switch

若有超過2種以上的可能,用if else難以閱讀,便可用switch的陳述式。

語法(Syntax)

switch(expression) {
  case x:
    break;
  case y:
    break;
  default:
}

expression依依由上而下一一比對case的值,若比對成功則執行相對應的邏輯。

Example

var week = new Date().getDay();
var displayWeek = '';
switch (week) {
    case 1:
        displayWeek = "星期一";
        break;
    case 2:
        displayWeek = "星期二";
        break;
    case 3:
        displayWeek = "星期三";
        break;
    case 4:
        displayWeek = "星期四";
        break;
    case 5:
        displayWeek = "星期五";
        break;
    default:
        // 1,6
        displayWeek = "周末";
        break;
}

break

跳出該case的邏輯,若沒設定break; 還會進到下一個case去,不管符不符合

default

  • 當沒有case比對到的時候,就無條件執行default。
  • 不一定要放在最後
  • 若沒有放在最後,記得加 break;

其他

  • 兩個case可以用同一段邏輯
...
case 1:
case 2:
  // logic
  break;
...
  • 如果多個case都成立,只會執行最先符合的case
  • 如果沒有case成立,就執行default邏輯
  • 如果連default都沒有,則跳出switch陳述式
  • switch的比對是用===來比對,也就是說值和型別都須符合

[Back To Basic] Javascript - 條件判斷(Conditions)

if, else, else if

共三個保留字(大小寫要注意)
  • if
  • else
  • else if
e.g.
var now = new Date().getHours();
var response = "";
if(now < 12) {
  response = "morn";
} else if (now < 18) {
  response = "after noon";
} else {
  response = "leisure time";
}

2019年3月4日 星期一

[Back To Basic] Javascript - 比較運算和邏輯運算(Comparison and Logical Operators)

比較運算和邏輯運算的結果為true或false

比較運算符號(Comparison Operators)

  • ==
值相等
  • ===
值相等 且 型別相等
  • !=
值不相等
  • !==
值不相等 或 型別不相等
  • >
大於
  • <
小於
  • >=
大於等於
  • <=
小於等於

邏輯運算符號(Logical Operators)

  • &&
  • ||
  • !
非(not)

條件/三元運算(Conditional / Ternary Operator)

語法: variable = (condition) ? value1:value2;
e.g. var isLeader = (role==="Leader") ? true : false;

不同型別的比對

盡量避免不同型別的比對,比對前應先轉換型別。


[Back To Basic] Javascript - 布林(booleans)

布林(booleans)型別

  • 代表變數值只能式 true 或 false
  • 是比較和條件的基礎
  • 變數只要有值就是true
    • e.g. var var1 = Boolean("False"); // var1 為 true
  • 變數只要沒有值就是false
    • e.g. var var 1 = Boolean(0) // var1 為 false
    • e.g. var var 2 = Boolean(-0) // var2 為 false
    • e.g. var var 3 = Boolean("") // var3 為 false
    • e.g. var var 4 = Boolean(undefined) // var4 為 false
    • e.g. var var 5 = Boolean(null) // var5 為 false
    • e.g. var var 6 = Boolean(false) // var6 為 false
    • e.g. var var 7 = Boolean(NaN) // var7 為 false
  • 也可用object的方式新增,但強烈建議不要使用這種方式
    • var var1 = new Boolean(true);
    • var var2 = new Boolean(false);

[Back To Basic] Javascript - 亂數(random)

Math.random()

回傳0~1之間的數,包含0,不包含1

延伸應用

  • 產生0~9的亂數
Math.floor(Math.random() * 10);
  • 產生0~10的亂數
Math.floor(Math.random() * 11);
  • 產生0~99的亂數
Math.floor(Math.random() * 100);
  • 產生0~100的亂數
Math.floor(Math.random() * 101);
  • 產生1~10的亂數
Math.floor(Math.random() * 10) + 1;
  • 產生1~100的亂數
Math.floor(Math.random() * 100) + 1;

共用函數

  • 產生min~max間的數字(不包含max)
e.g. getRndInteger(1, 10): 可能產生1~9

function getRndInteger(min, max) {
  return Math.floor(Math.random() * (max - min) ) + min;
}
  • 產生min~max間的數字(包含max)
e.g. getRndInteger(1, 10): 可能產生1~10

function getRndInteger(min, max) {
  return Math.floor(Math.random() * (max - min + 1) ) + min;
}