本篇是關於手寫代碼的題目。 1.實現一個trim函數 關於性能的寫法也不多說了,只是用最直觀的寫法來寫一下,使用正則有大概五六種寫法,感興趣可以自己去研究下,推薦《高性能JavaScript》 1.正則實現 trim leftTrim rightTrim 2.非正則實現 trim leftTrim ...
本篇是關於手寫代碼的題目。
1.實現一個trim函數
關於性能的寫法也不多說了,只是用最直觀的寫法來寫一下,使用正則有大概五六種寫法,感興趣可以自己去研究下,推薦《高性能JavaScript》
1.正則實現
trim
String.prototype.trim = function () { return this.replace(/(^\s*)|(\s*$)/g, ""); }
leftTrim
String.prototype.leftTrim = function () { return this.replace(/(^\s*)/g,""); }
rightTrim
String.prototype.rightTrim = function () { return this.replace(/(\s*$)/g,""); }
2.非正則實現
trim
String.prototype.trim = function () { var start = 0, end = this.length - 1, ws = /\s/ while (ws.indexOf(this.charAt(start)) > -1) { start ++ } while (end > start && ws.indexOf(this.charAt(end)) > -1) { end -- } return this.slice(start, end + 1) }
leftTrim
String.prototype.leftTrim = function () { var start = 0, end = this.length - 1, ws = /\s/ while (ws.indexOf(this.charAt(start)) > -1) { start ++ } return this.slice(start, end) }
rightTrim
String.prototype.rightTrim = function () { var start = 0, end = this.length - 1, ws = /\s/ while (end > start && ws.indexOf(this.charAt(end)) > -1) { end -- } return this.slice(start, end + 1) }
3.混合實現
當字元串的末尾只有一小段空白時候,正則表達式會陷入瘋狂工作狀態;而通過迴圈遍歷字元串的效率也比不上正則表達式,所以有了這種混合模式
String.prototype.trim = function () {
var str = this.replace(/^\s+/, '')
end = str.length - 1
ws = /\s/
while (ws.test(str.charAt(end))) {
end --
}
return str.slice(0, end + 1)
}
2.call、apply、bind之間的區別
總之三種方法都是改變函數內this的指向
1.fn.call (context, arg1, arg2, .....)
call中第一個參數是fn的上下文,剩下的參數就是需要向fn中傳遞的參數
2.fn.apply (context, [args])
apply同call類似,第一個參數也是fn的上下文,和call不同的是,apply第二個參數是數組,call的第二個及第二個以後的參數都是數組裡面的元素
3.fn.bind (context)
bind會創建一個函數,稱之為綁定函數,調用這個函數時,綁定函數會以創建它是bind方法傳入的第一個參數作為自己的上下文,第二個及第二個以後的參數並且加上綁定函數運行時傳遞進來的參數作為原函數的參數來調用原函數。 (有點繞哈,不過對下一道題有幫助)
4.call、apply、bind最大的區別就是bind不會立即調用,會返回一個函數,apply、call會立即調用。
3.用call或者apply實現一個bind函數
看看上面的bind定義吧,不多說了
if (!Function.prototype.bind) {
Function.prototype.bind = function (oThis) {
if (typeof this !== "function") {
throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
}
var aArgs = Array.prototype.slice.call(arguments, 1),
fToBind = this,
fNOP = function () {},
fBound = function () {
return fToBind.apply(this instanceof fNOP && oThis
? this
: oThis || window,
aArgs.concat(Array.prototype.slice.call(arguments)));
};
fNOP.prototype = this.prototype;
fBound.prototype = new fNOP();
return fBound;
};
}