JavaScript: The Good Parts
Methods & Styles
Agenda
- JavaScript 常見的"方法 "
- JavaScript 的 Coding Style
常見的"方法"
今天將會提到的方法
- Array
- Function
- Number
- Object
- RegExp
- String
Array
Array
- sort
- concat
- join
- pop
- push
- reverse
- shift
- slice
- splice
- unshift
Array.sort
// 用法 array.sort(compareFn)
// 排序array內容
var array = [12, 8, 41];
array.sort();
// 預期: [8, 12, 41]
// output: [12, 41, 8] (unexpected result)
sort沒那麼聰明
sort 預設會array內的元素轉成字串, 導致排序的結果可能會不如預期
自訂排序函數
Array.sort
// 用法 array.sort(compareFn)
// 排序array內容
// 比較函數: compareFn, 應傳入兩個參數,
// 當compareFn回傳是負數, 則第一個參數放入array的優先權較高
// 當compareFn回傳是正數, 則第二個參數放入array的優先權較高
// 當compareFn回傳0 代表兩參數放入array的優先權相同
var array = [12, 8, 41];
var ascFn = function(a, b){
return a-b
}
array.sort(ascFn);
// 預期: [8, 12, 41]
// output: [8, 12, 41] good!
Array.concat
// 用法 array.concat(item, item, ...)
// 將item加入到array的末端, item可以是array, object, boolean, undefined, null
// ※ item若是array, concat則會將item內的元素一一取出並加入array末端
var target = ["a1", "a2", "a3"];
var source = ["b1", "b2", "b3"];
var concatArray = [];
concatArray = target.concat(source, "c1", true, undefined, null, {"a": "123"}, function aaa(){});
// output: ["a1", "a2", "a3", "b1", "b2", "b3", "c1", true, undefined, null, Object, function]
Array.join
// 用法: array.join(separator)
// separator: 用來區隔array合併成String時, 區隔各個元素的符號
var date= ["2017", "01", "01"]
var rs = ""
rs = date.join("-")
// output: "2017-01-01"
Array.pop
// 用法: array.pop()
// 移除並回傳array最後一個元素
var array= ["a", "b", "c"]
var rs = array.pop();
// rs = "c";
Array.push
// 用法: array.push(item)
// 將item加入array最後一個位置
// ※ 與concat不同之處: push會回傳array的新長度
var array= ["a", "b", "c"]
var rs = array.push("d");
// rs = 4;
Array.push
// 用法: array.push(item)
// 將item加入array最後一個位置
// ※ 與concat不同之處: push會回傳array的新長度
var array= ["a", "b", "c"]
var rs = array.push("d");
// rs = 4;
Array.reverse
// 用法: array.reverse()
// 反轉array內元素的順序, 並回傳array
var array = ["a", "b", "c"]
var rs = array.reverse();
// rs= ["c", "b", "a"];
Array.shift
// 用法: array.shift()
// 移除並回傳array第一個元素
// ※ shift通常比pop速度慢很多
var array = ["a", "b", "c"]
var rs = array.shift();
// rs = "a";
// array = ["b", "c"];
Array.slice
// 用法: array.slice(start, end)
// slice將從start位置開始複製元素, 一直到end的位置則停止複製, 並將複製的元素加入到一個新的array, 最後回傳新array
// start: 可不填寫, 預設為 0
// end: 可不填寫, 預設為array.length
var array = ["a", "b", "c"]
var rs1 = array.slice(1, 2);
var rs2 = array.slice(1);
// rs1 = ["b"]
// rs2 = ["b", "c"]
Array.splice
// 用法: array.splice(start, deleteCount, item)
// splice將從start位置開始移除deleteCount個元素,並以item取代, 最後將移除的元素放入新的array內回傳
// 常見用途: 刪除元素
var array = ["a", "b", "c"]
var rs = array.splice(1, 1, "bbb");
// rs = ["b"]
// array = ["a", "bbb", "c"]
Array.unshift
// 用法: array.unshift(item, ...)
// 將item加入array最前端
// ※ 與push類似, 不同之處: push將item加入array末端, 並回傳array的新長度
var array = ["a", "b", "c"]
var rs = array.unshift("ddd", "eee");
// rs = 5
// array = ["ddd", "eee", "a", "b", "c"]
Function
function.apply
var a = function(a1, a2, a3){
this.list = [a1, a2, a3]
return this
}
// try below
var rs = a.apply(null, ["a", "b", "c", "d"])
var rs = a.apply({}, ["a", "b", "c", "d"])
function.apply
Function.method("bind", function(that){
console.log("that===========>", that);
console.log("this===========>", this);
var method = this,
slice = Array.prototype.slice,
args = slice.apply(arguments, [1])
console.log("slice.apply(arguments, [1])============>", slice.apply(arguments, [1]))
console.log("slice.apply(arguments, [0])============>", slice.apply(arguments, [0]))
console.log("args.concat(slice.apply(arguments, [0])====>", args.concat(slice.apply(arguments, [0])));
return function(){
return method.apply(that,
args.concat(slice.apply(arguments, [0]))
)
}
});
var x = function(){
return this.value;
}.bind({value: 666});
alert(x()); ///666
//make a method available to all functions by augmenting Function.prototype
Function.prototype.method = function (name, func) {
this.prototype[name] = func;
return this;
};
Number
Number
- toExponential
- toFixed
- toPrecision
- toString
Number.toFixed
// 用法 Number.toFixed(fractionDigits)
// 四捨五入小數點後方第fractionDigits+1的數字, 並回傳整數以及小數點後方第fractionDigits位置
// ※ 回傳值為字串屬性
// 0 <= fractionDigits <= 20
var num= 9487.9487;
num.toFixed(2);
// output: "9487.95"
Number.toPrecision
// 用法 Number.toPrecision(precision)
// 確保回傳n個整數位以及小數後後面precision-n個位數, 並先四捨五入小數點後方precision-n+1的數字
// 常用在"無理數", 也就是小數點後方有無限多個數字
// ※ 回傳值為字串屬性
// precision預設是16
// 1 <= precision <= 21
var num= 9487.9487;
num.toPrecision(5);
// output: "9487.9"
num.toPrecision(3);
// output: "9.49e+3"
Number.toString
// 用法 Number.toString(radix)
// 可將數字轉成"radix進位"後, 再轉成字串格式回傳
// radix預設是10
// 2 <= radix <= 36
var num= 8;
num.toString(2);
// output: "1000"
Object
Object.hasOwnProperty
// 用法 Object.hasOwnProperty(name)
// 檢查Object內是否有name這個屬性
// ※ 回傳值為bool值
var a = {"val": "123"}
a.hasOwnProperty("val") // output: true
a.hasOwnProperty("val1") // output: false
// 不檢查Object預設給的prototype屬性
a.hasOwnProperty("hasOwnProperty") // output: false
RegExp
RegExp
- exec
- test
regexp.exec()
// 用法 regexp.exec(str)
// 用正規表示法比對str
// 若有找到符合規則的字串, 則回傳陣列, 陣列的第一個位置代表與regexp符合的字串
// 當無法在str內找到符合的字串ㄝ, 則會傳null
// ※ 最強大,但速度最慢的正規示使用方法
/Example 1: 正規表示法內加上"g" /
var myRe = /ab*/g;
var str = 'abbcdefabh';
var myArray;
myArray = myRe.exec(str) // 第一次執行, 回傳:["abb", index: 0, input: "abbcdefabh"]
myArray = myRe.exec(str) // 第二次執行, 回傳:["ab", index: 7, input: "abbcdefabh"]
/Example 2: 正規表示法後方不加上"g" /
var myRe = /ab*/;
var str = 'abbcdefabh';
var myArray;
myArray = myRe.exec(str) // 第一次執行, 回傳:["abb", index: 0, input: "abbcdefabh"]
myArray = myRe.exec(str) // 第二次執行, 回傳:["abb", index: 0, input: "abbcdefabh"]
regexp.test()
// 用法 regexp.test(str)
// str符合regexp規則則回傳true, 否則回傳false
// ※ regexp不能加入"g", 與test一起併用
// 最簡單, 也最快的正規表示方法
var myRe = /ab*/;
var str = 'abbcdefabh';
var myArray;
myArray = myRe.test(str) // true
String
String
- charAt
- charCodeAt
- concat
- IndexOf
- lastIndexOf
- localeCompare
- match
- replace
- search
- slice
- split
- substring
- toLocaleLower
- toLowerCase
- UpperCase
- fromCharCode
方法太多, 就不一一介紹了
今天就介紹幾個MDN 是神物
名稱 | charAt(pos) | charCodeAt(pos) |
---|---|---|
功能 | 回傳pos位置上的字元 | 回傳pos位置字元的code point值 |
差異 | 回傳值: 字元 | 回傳值: code point值 |
範例 | let name = "ceall" let char = name.charAt(1); // char = "e" |
let name = "ceall" let char = name.charCodeAt(1); // char = 101 |
charAt VS charCodeAt
名稱 | indexOf (searchStr, pos) | lastIndexOf (searchStr, pos) |
---|---|---|
功能 | 回傳searchStr在string位置中的索引值。 pos: optional, 可指定搜尋的起始位置 |
回傳searchStr在string位置中的索引值 pos: optional, 可指定搜尋的起始位置 |
差異 | 從頭開始搜尋 | 從末端開始搜尋 |
範例 | let name = "Mississippi" let index = name.indexOf ("ss"); // index = 2 index = name.indexOf ("ss", 3); // index = 5 index = name.indexOf ("ss", 6); // index = -1 |
let name = "Mississippi" let index = name.lastIndexOf("ss"); // index = 5 index = name.lastIndexOf("ss", 3); // index = 2 index = name.lastIndexOf("ss", 6); // index = 5 |
indexOf VS lastIndexOf
String.localeCompare
// 用法 String.localeCompare(that)
// string 與that比較, 比較兩string的第一個字元
// that順序在string前面則回傳1, 反之回傳-1
var a = "abc"
var b = "bac"
a.localeCompare(b)
//output: -1
var arr = ['AAA', 'A', 'aa', 'a', 'Aa', 'aaa']
m.sort(function (a, b){
return a.localeCompare(b);
})
//m: ["a", "A", "aa", "Aa", "aaa", "AAA"]
String.match
// 用法 String.match(regexp)
// regexp沒有包含標籤"g", 則運行的方式與regexp.exec(string)相同
// 如果有包含標籤"g",
//沒有標籤'g'
var myRe = /ab*/;
var str = 'abbcdefabh';
str.match(myRe) //output: ["abb", index: 0, input: "abbcdefabh"]
//有標籤'g'
var myRe = /ab*/g;
var str = 'abbcdefabh';
str.match(myRe) //output: ["abb", "ab"]
String.replace
// 用法 String.replace(searchValue, replaceValue)
// searchValue若為字串, 則只有第一個出現的searchValue被取代
// searchValue若為正規表示法. 並且包含標籤'g', 則所有searchValue將都被取代, 若沒有加入標籤'g', 則只會取代第一個出現的searchValue
// replaceValue可以是自串, 也可以是function
// 範例1
var str = "apples are round, and apples are juicy.";
var newstr = str.replace("apples", "oranges");
// output: "oranges are round, and apples are juicy."
// 範例2
var re = /apples/gi;
var str = "Apples are round, and apples are juicy.";
var newstr = str.replace(re, "oranges");
// output: "oranges are round, and oranges are juicy."
// 範例3
var re = /(\w+)\s(\w+)/;
var str = "John Smith";
str.match(re) // ["John Smith", "John", "Smith", index: 0, input: "John Smith"]
var newstr = str.replace(re, "$2, $1"); // "Smith, John"
//範例4
var str = "apples are round, and apples are juicy.";
var newstr = str.replace(/apples/gi, function(arg1, arg2, arg3){
// arg1 符合正規表示式的字串
// 字串的位置索引值
// str字串
console.log("arg1", arg1) // apples, apples
console.log("arg2", arg2) // 0, 22
console.log("arg3", arg3) // "apples are round, and apples are juicy.", "apples are round, and apples are juicy."
});
String.search
// 用法 String.search(regexp)
// 回傳符合正規表示示規則的字串片段位置, 若搜尋失敗則回傳-1
// 若加入標籤"g", 則將被忽略
var myRe = /ab*/;
var str = 'abbcdefabh';
str.search(myRe) // 0
String.slice
// 用法 String.slice(start, end)
// 方法與參數的定義同Array
// start代表slice複製字元的起點, 若是複製cnt個字元, 則end = start + cnt;
let str = "An apple a day, keeps the doctor away"
let getApple = str.slice(3, 8); // "apple"
let getSecSentence = str.slice(-21) // "keeps the doctor away"
String.split
// 用法 String.split(separator, limit)
// split依照separator分割字串, 並將分割的元素放入新的字串
// separator可以是符號也可以是正規表示式
// limit: 分割後, 新的array內的元素數量最多不能超過limit
let str = "012345"
str.split('',2); // ["0", "1"] (本書解答有誤)
String.substring
// 用法 String.substring(start, end)
// 與slice方法一致
// 不同之處: 參數不能帶負數
// substring, slice擇一使用即可
String.toLocaleLowerCase
// 用法 String.toLocaleLowerCase()
// 將所有字母轉換成小寫, 並依主機目前環境設定列入考慮
// 因土耳其語的某些字母轉換成小寫與英語不同, toLowerCase反而不實用
String.fromCharCode
// 用法 String.fromCharCode(char, ...)
// char, 輸入數值
// fromCharCode將數值轉換成字串
var a = String.fromCharCode(67, 97, 116); // "Cat"
Coding Style
Why ?
Reasons
- 需要考慮到未來修改程式結構的可能性
- 增加易讀性
- 易讀性高的code會提高工程師工作意願的可能性
What are the suggestions?
Suggestions
- 每次縮排空四個空格
- '(', '{' 等符號, 皆在前方加入空格
- ex: if () {};
- 盡量一句敘述就一行
- 逗號或雙元運算子(!=, ==)後才換行
- 避免JavaScript自動加入分號時造成錯誤
- 需更新註解
- 區塊型註解用來較正式的說明或是關閉原始碼的說明
- 應該每個程式開端宣告所有變數
- JavaScript允許變數可在被使用後才宣告
- 善用closure建立資訊隱藏
Title Text
Javascript Good Part - Javascript Methods & Coding Styles介紹
By ceall
Javascript Good Part - Javascript Methods & Coding Styles介紹
- 966