JS字符串補全方法padStart()和padEnd()簡介

本文轉載至張鑫旭的博文 from www.zhangxinxu.com/wordpress/?…

1、關於字符串補全

在JS中,字符串補全是經常使用操做,用的比較多的就是時間或者日期前面的補0
javascript

例如,日期,咱們多采用4-2-2的表示形式,例如:php

2018-07-23複製代碼

當咱們使用時間戳進行月份獲取的時候,是沒有前面的0的,例如:前端

var month = new Date().getMonth() + 1;    // 結果是7複製代碼

此時,就須要進行補全,一般作法是這樣:java

if (month < 10) {
    month = '0' + month;
}複製代碼

甚至會專門定義一個補'0'方法,例如此日期轉時間戳微碼中的自定義的zero方法。git

補全方法代碼示意

然而,隨着JS字符串補全方法padStart()padEnd()的出現,相似場景使用就簡單多了!github

2、關於padStart

padStart能夠在字符串的開頭進行字符補全。windows

語法以下:後端

str.padStart(targetLength [, padString])複製代碼

其中:瀏覽器

targetLength (可選)
targetLength指目標字符串長度。

而後,根據個人測試,targetLength參數缺省也不會報錯,本來的字符串原封不動返回,不過代碼沒有任何意義,所以,基本上沒有使用的理由。less

還有,targetLength參數的類型能夠是數值類型或者弱數值類型。在JavaScript中,1 == '1'1是數值,'1'雖然本質上是字符串,但也能夠當作是弱數值。在padStart()方法中,數值類型或者弱數值類型都是能夠。例如:

'zhangxinxu'.padStart('5');複製代碼

所以,咱們實際使用的時候,不必對targetLength參數進行強制的類型轉換。

最後,若是targetLength設置的長度比字符串自己還要小,則本來的字符串原封不動返回,例如:

'zhangxinxu'.padStart(5);    
// 結果仍是'zhangxinxu'複製代碼
padString (可選)
padString表示用來補全長度的字符串。然而,雖然語義上是字符串,可是根據個人測試,任意類型的值都是能夠的。不管是Chrome瀏覽器仍是Firefox瀏覽器,都會嘗試將這個參數轉換成字符串進行補全。例以下面幾個例子:

'zhangxinxu'.padStart(15, false);
// 結果是'falsezhangxinxu'複製代碼
'zhangxinxu'.padStart(15, null);
// 結果是'nullnzhangxinxu'複製代碼
'zhangxinxu'.padStart(15, []);
// 結果是'zhangxinxu',由於[]轉換成字符串是空字符串複製代碼
'zhangxinxu'.padStart(15, {});
// 結果是'[objezhangxinxu',只顯示了'[object Object]'前5個字符複製代碼

padString參數默認值是普通空格' '(U+0020),也就是敲Space空格鍵出現的空格。

從上面幾個案例能夠看出,若是補全字符串長度不足,則不斷循環補全;若是長度超出,則從左側開始依次補全,沒有補到的字符串直接就忽略。

此方法返回值是補全後的字符串。

回到一開始的日期補'0'功能,有了padStart()方法,咱們代碼能夠簡化成下面這一行:

var month = String(new Date().getMonth() + 1).padStart(2, '0');    // 結果是'07'複製代碼

兼容性

IE14以其已下瀏覽器都不支持,考慮到如今仍是windows 7天下,PC端對外項目還不能直接用;移動端,UC瀏覽器,QQ瀏覽器也不支持。可是,也不是不能使用,加一個Polyfill就行了,這個後面會展現。

3、關於padEnd

padEnd能夠在字符串的後面進行字符補全,語法參數等都和padStart相似。

語法:

str.padEnd(targetLength [, padString])複製代碼

其中:

targetLength (可選)
targetLength指補全後字符串的長度。

而後,根據個人測試,targetLength參數若是不設置,不會報錯,直接返回原始字符串,不過這樣代碼就沒有任何意義,所以,實際開發,此參數確定是須要設置的。

一樣的,targetLength參數的類型能夠是數值類型或者弱數值類型。例以下面2個用法都是能夠的:

'zhangxinxu'.padEnd('15');
'zhangxinxu'.padEnd(15);複製代碼

所以,咱們實際寫代碼的時候,不必強制targetLength參數爲數值。

最後,若是targetLength設置的長度比字符串自己還要小,則原字符串原封不動返回,例如:

'zhangxinxu'.padEnd(5);    
// 結果仍是'zhangxinxu'複製代碼

若是targetLength是一些亂七八糟的數值類型,也是返回原始字符串。例如:

'zhangxinxu'.padEnd(false);    
// 結果仍是'zhangxinxu'複製代碼

可是有意義嗎?沒意義,因此不要這麼用。

padString (可選)
padString表示用來補全長度的字符串。雖然語義上是字符串,實際上這個參數能夠是各類類型。例以下面幾個例子:

'zhangxinxu'.padEnd(15, false);
// 結果是'zhangxinxufalse'複製代碼
'zhangxinxu'.padEnd(15, null);
// 結果是'zhangxinxunulln'複製代碼
'zhangxinxu'.padEnd(15, []);
// 結果是'zhangxinxu',由於[]轉換成字符串是空字符串複製代碼
'zhangxinxu'.padEnd(15, {});
// 結果是'zhangxinxu[obje',只顯示了'[object Object]'前5個字符複製代碼

從上面幾個案例能夠看出,若是補全字符串長度不足,則從左往右不斷循環補全;若是長度超出能夠補全的字符長度,則從左側儘量補全,補不到的沒辦法,只能忽略,例如'zhangxinxu'.padEnd(15, {})等同於執行'zhangxinxu'.padEnd(15, '[object Object]'),最多隻能補5個字符,所以,只能補'[object Object]'前5個字符,因而最後結果是:'zhangxinxu[obje'

padString參數若是不設置,則會使用普通空格' '(U+0020)代替,也就是Space空格鍵敲出來的那個空格。

舉一個在後面補全字符串案例
在JS前端咱們處理時間戳的時候單位都是ms毫秒,可是,後端同窗返回的時間戳則不同是毫秒,可能只有10位,以s秒爲單位。因此,咱們在前端處理這個時間戳的時候,保險起見,要先作一個13位的補全,保證單位是毫秒。使用示意:

timestamp = +String(timestamp).padEnd(13, '0');複製代碼

兼容性

本字符串API屬於ES6新增方法,IE14以其已下瀏覽器都不支持,部分國產移動端瀏覽器也不支持。目前對外項目使用還須要附上Polyfill代碼。

4、Polyfill代碼

如下Polyfill代碼取自polyfill項目中的string.polyfill.js,其中使用依賴的repeat()也是ES6新增方法,所以,完成Polyfill代碼以下,註釋部分我作了簡單的翻譯,代碼部分簡化了些許邏輯,同時,修復了一個bug,下面代碼紅色高亮部分就是修復內容:

// https://github.com/uxitten/polyfill/blob/master/string.polyfill.js
// repeat()方法的polyfill
if (!String.prototype.repeat) {
    String.prototype.repeat = function (count) {
 'use strict';
        if (this == null) {
            throw new TypeError('can\'t convert ' + this + ' to object');
        }
        var str = '' + this;
        count = +count;
        if (count != count) {
            count = 0;
        }
        if (count < 0) {
            throw new RangeError('repeat count must be non-negative');
        }
        if (count == Infinity) {
            throw new RangeError('repeat count must be less than infinity');
        }
        count = Math.floor(count);
        if (str.length == 0 || count == 0) {
            return '';
        }
        if (str.length * count >= 1 << 28) {
            throw new RangeError('repeat count must not overflow maximum string size');
        }
        var rpt = '';
        for (; ;) {
            if ((count & 1) == 1) {
                rpt += str;
            }
            count >>>= 1;
            if (count == 0) {
                break;
            }
            str += str;
        }
        return rpt;
    }
}
// padStart()方法的polyfill
if (!String.prototype.padStart) {
    String.prototype.padStart = function (targetLength, padString) {
        // 截斷數字或將非數字轉換爲0
        targetLength = targetLength>>0; 
        padString = String((typeof padString !== 'undefined' ? padString : ' '));
        if (this.length > targetLength || padString === '') {
            return String(this);
        }
        targetLength = targetLength-this.length;
        if (targetLength > padString.length) {
            // 添加到初始值以確保長度足夠
            padString += padString.repeat(targetLength / padString.length); 
        }
        return padString.slice(0, targetLength) + String(this);
    };
}
// padEnd()方法的polyfill
if (!String.prototype.padEnd) {
    String.prototype.padEnd = function (targetLength, padString) {
        // 轉數值或者非數值轉換成0
        targetLength = targetLength >> 0; 
        padString = String((typeof padString !== 'undefined' ? padString : ' '));
        if (this.length > targetLength || padString === '') {
            return String(this);
        }
        targetLength = targetLength - this.length;
        if (targetLength > padString.length) {
            // 添加到初始值以確保長度足夠
            padString += padString.repeat(targetLength / padString.length);
        }
        return String(this) + padString.slice(0, targetLength);
    };
}複製代碼

以上polyfill代碼須要放在調用padStart()/padEnd()方法的代碼的前面,只要在合適的位置就這麼一粘貼,而後,不管什麼版本瀏覽器瀏覽器,哪怕IE6,IE8,咱們也能夠放心使用padStart()或者padEnd()方法了。

polyfill代碼下的demo案例

您能夠狠狠地點擊這裏:padStart和padEnd方法polyfill測試demo

原polyfill方法的一個bug就是經過這個測試demo測出來的,下面是修正後的polyfill代碼在IE9瀏覽器的測試結果截圖:

測試結果截圖

5、結語

標題雖然是簡介,可是本文內容實際上已經很是深刻細節了。padStart()padEnd()兩個方法參數容錯性很是強,很是有JS的特點,我很喜歡。可是,也帶來另外的問題,就是,若是咱們的參數值由於各類緣由,最後並非咱們指望的參數值,則極可能會產生很是隱蔽的bug,由於不會報錯啊,運行仍是正常的。因此,容錯性強,也算是有利有弊。

相關文章
相關標籤/搜索