一、前言
之前寫了一篇文章:JavaScript 系列--JavaScript一些奇淫技巧的實現方法(一)簡短的sleep函式,獲取時間戳
https://www.mwcxs.top/page/746.html
介紹了sleep函式和獲取時間戳的方法。接下來我們來介紹數字格式化1234567890 --> 1,234,567,890
二、數字格式化 1234567890 --> 1,234,567,890
1、普通版
// 數字格式化 1234567890 --> 1,234,567,890
function formatNumber(str){
var arr = [];
var count = str.length;
while(count>=3){
arr.unshift(str.slice(count - 3, count));
count -= 3;
}
// 如果是不是3的倍數就另外追加到上去
str.length % 3 && arr.unshift(str.slice(0, str.length % 3));
return arr.toString();
}
formatNumber('1234567890')
優點:自我感覺比網上寫的一堆 for迴圈 還有 if-else 判斷的邏輯更加清晰直白。
缺點:太普通
2、進階版
// 2、進階版
function formatNumber(str){
return str.split("").reverse().reduce((prev,next,index) => {
return ((index%3)? next: (next+',')) + prev;
})
}
formatNumber("1234567890");
優點:把 JS 的 API 玩的瞭如指掌
缺點:不好理解
3、正則版
function formatNumber(str){
return str.replace(/(?!^)(?=(\d{3})+$)/g,',')
}
formatNumber("1234567890");
我們來看看正則的分析:
(1)/(?!^)(?=(\d{3})+\b)/g:匹配的這個位置不能是開頭(?!^)
(2)(\d{3})+:必須是1個或者多個的3個連續數字
優點:程式碼少,簡潔。
缺點:正規表示式的位置匹配很重要,可以參考這個:https://www.mwcxs.top/page/587.html
4、API版本
(1234567890).toLocaleString('en-us');
(1234567890).toLocaleString();
1234567890..toLocaleString();
你可能還不知道 JavaScript
的 toLocaleString
還可以這麼玩。
123456789..toLocaleString('zh-hans-cn-u-nu-hanidec',{useGrouping: false}); //"一二三四五六七八九"
123456789..toLocaleString('zh-hans-cn-u-nu-hanidec',{useGrouping: false}); //"一二三,四五六,七八九"
new Date().toLocaleString('zh-hans-cn-u-nu-hanidec'); //"二〇一九/五/二九 下午三:一五:四〇"
還可以使用Intl物件,
Intl 物件是 ECMAScript 國際化 API 的一個名稱空間,它提供了精確的字串對比,數字格式化,日期和時間格式化。Collator,NumberFormat 和 DateTimeFormat 物件的建構函式是 Intl 物件的屬性。
new Intl.NumberFormat().format(1234567890) // 1,234,567,890
優點:簡單粗暴,直接呼叫api
缺點:Intl相容性不太好,不過 toLocaleString的話 IE6 都支援
前端知識點:Intl物件 和 toLocaleString的方法。
三、argruments 物件(類陣列)轉換成陣列
那什麼是類陣列?就是跟陣列很像,但是他是物件,格式像陣列所以叫類陣列。比如:{0:a,1:b,2:c,length:3},按照陣列下標排序的物件,還有一個length的屬性,有時候我們需要這種物件能呼叫陣列下的一個方法,這時候就需要把把類陣列轉化成真正的陣列。
1、普通版
var makeArray = function(arr){
var res = [];
if(arr != null){
var i = arr.length;
if(i == null || typeof arr == "string") res[0] = arr;
else while(i){res[--i] = arr[i];}
}
return res;
};
var obj = {0:'a',1:'b',2:'c',length:3};
makeArray(obj);
優點:通用版本,沒有任何相容性問題
缺點:暫時沒有啥缺點
2、進階版
// 2、進階版
var arr = Array.prototype.slice.call(arguments);
大家用過最常用的方法,至於為什麼可以這麼用,很多人估計也是一知半解,要搞清為什麼裡面的原因,我們還是從規範和原始碼說起。
slice.call
的作用原理就是,利用 call
,將 slice
的方法作用於 arrayLike
,slice
的兩個引數為空,slice
內部解析使得 arguments.lengt
等於0的時候 相當於處理 slice(0)
: 即選擇整個陣列,slice
方法內部沒有強制判斷必須是 Array
型別,slice
返回的是新建的陣列(使用迴圈取值)”,所以這樣就實現了類陣列到陣列的轉化,call
這個神奇的方法、slice
的處理缺一不可。
直接看 slice
怎麼實現的吧。其實就是將 array-like
物件通過下標操作放進了新的 Array
裡面,下面是原始碼
// This will work for genuine arrays, array-like objects,
// NamedNodeMap (attributes, entities, notations),
// NodeList (e.g., getElementsByTagName), HTMLCollection (e.g., childNodes),
// and will not fail on other DOM objects (as do DOM elements in IE < 9)
Array.prototype.slice = function(begin, end) {
// IE < 9 gets unhappy with an undefined end argument
end = (typeof end !== 'undefined') ? end : this.length;
// For native Array objects, we use the native slice function
if (Object.prototype.toString.call(this) === '[object Array]'){
return _slice.call(this, begin, end);
}
// For array like object we handle it ourselves.
var i, cloned = [],
size, len = this.length;
// Handle negative value for "begin"
var start = begin || 0;
start = (start >= 0) ? start : Math.max(0, len + start);
// Handle negative value for "end"
var upTo = (typeof end == 'number') ? Math.min(end, len) : len;
if (end < 0) {
upTo = len + end;
}
// Actual expected size of the slice
size = upTo - start;
if (size > 0) {
cloned = new Array(size);
if (this.charAt) {
for (i = 0; i < size; i++) {
cloned[i] = this.charAt(start + i);
}
} else {
for (i = 0; i < size; i++) {
cloned[i] = this[start + i];
}
}
}
return cloned;
};
優點:最常用的版本,相容性強。
缺點:ie 低版本,無法處理 dom 集合的 slice call 轉陣列。
3、ES6版
使用 Array.from
, 值需要物件有 length
屬性, 就可以轉換成陣列。
var arr = Array.from(arguments);
擴充套件運算子
var args = [...arguments];
ES6
中的擴充套件運算子...也能將某些資料結構轉換成陣列,這種資料結構必須有便利器介面。
優點:直接使用內建 API,簡單易維護
缺點:相容性,使用 babel 的 profill 轉化可能使程式碼變多,檔案包變大
前端知識點:slice 方法的具體原理
【注:我是saucxs,也叫songEagle,鬆寶寫程式碼,文章首發於sau交流學習社群(https://www.mwcxs.top),關注我們每天閱讀更多精彩內容】