JS字符串补全方法padStart()和padEnd()简介

简介: JS字符串补全方法padStart()和padEnd()简介

一、关于字符串补全

在JS中,字符串补全是常用操作,用的比较多的就是时间或者日期前面的补0

例如,日期,我们多采用4-2-2的表示形式,例如:

2018-07-23

当我们使用时间戳进行月份获取的时候,是没有前面的0的,例如:

var month = new Date().getMonth() + 1;    // 结果是7

此时,就需要进行补全,通常做法是这样:

if (month < 10) {
    month = '0' + month;
}

甚至会专门定义一个补'0'方法,例如此日期转时间戳微码中的自定义的zero方法。

然而,随着JS字符串补全方法padStart()padEnd()的出现,类似场景使用就简单多了!

二、关于padStart

padStart可以在字符串的开头进行字符补全。

语法如下:

str.padStart(targetLength [, padString])

其中:

targetLength (可选)

targetLength指目标字符串长度。

然后,根据我的测试,targetLength参数缺省也不会报错,原本的字符串原封不动返回,不过代码没有任何意义,因此,基本上没有使用的理由。

还有,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就好了,这个后面会展示。

三、关于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代码。

四、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浏览器的测试结果截图:

五、结语

标题虽然是简介,但是本文内容实际上已经非常深入细节了。padStart()padEnd()两个方法参数容错性非常强,非常有JS的特色,我很喜欢。但是,也带来另外的问题,就是,如果我们的参数值因为各种原因,最后并不是我们期望的参数值,则很可能会产生非常隐蔽的bug,因为不会报错啊,运行还是正常的。所以,容错性强,也算是有利有弊。

ES6对字符串还扩展了很多其他方法,除了本文提到的repeat()方法,还有诸如normalize()trimStart()trimEnd()等API方法。这些之后再一个一个深入细节。


目录
相关文章
|
5月前
|
监控 负载均衡 JavaScript
有哪些有效的方法可以优化Node.js应用的性能?
有哪些有效的方法可以优化Node.js应用的性能?
299 69
|
4月前
|
JavaScript Linux 内存技术
Debian 11系统下Node.js版本更新方法详解
本指南详细介绍在Linux系统中安装和管理Node.js的步骤。首先检查现有环境,包括查看当前版本和清除旧版本;接着通过NodeSource仓库安装最新版Node.js并验证安装结果。推荐使用nvm(Node Version Manager)进行多版本管理,便于切换和设置默认版本。同时,提供常见问题解决方法,如权限错误处理和全局模块迁移方案,以及版本回滚操作,确保用户能够灵活应对不同需求。
322 0
|
4月前
|
JavaScript Linux 内存技术
Debian 11系统下Node.js版本更新方法
Debian 11更新Node.js主要就是这三种方式,无论你是初涉其中的新手还是找寻挑战的专家,总有一种方式能满足你的需求。现在,你已经是这个
341 80
|
11月前
|
JavaScript 前端开发 程序员
前端原生Js批量修改页面元素属性的2个方法
原生 Js 的 getElementsByClassName 和 querySelectorAll 都能获取批量的页面元素,但是它们之间有些细微的差别,稍不注意,就很容易弄错!
224 1
|
8月前
|
前端开发 JavaScript
有没有方法可以保证在JavaScript中多个异步操作的执行顺序?
有没有方法可以保证在JavaScript中多个异步操作的执行顺序?
311 58
|
6月前
|
JavaScript 前端开发 Java
js 垃圾回收机制的方法
JS回收机制方法讲解
|
7月前
|
JavaScript 前端开发 Java
深入理解 JavaScript 中的 Array.find() 方法:原理、性能优势与实用案例详解
Array.find() 是 JavaScript 数组方法中一个非常实用和强大的工具。它不仅提供了简洁的查找操作,还具有性能上的独特优势:返回的引用能够直接影响原数组的数据内容,使得数据更新更加高效。通过各种场景的展示,我们可以看到 Array.find() 在更新、条件查找和嵌套结构查找等场景中的广泛应用。 在实际开发中,掌握 Array.find() 的特性和使用技巧,可以让代码更加简洁高效,特别是在需要直接修改原数据内容的情形。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一
|
11月前
|
监控 JavaScript Java
Node.js中内存泄漏的检测方法
检测内存泄漏需要综合运用多种方法,并结合实际的应用场景和代码特点进行分析。及时发现和解决内存泄漏问题,可以提高应用的稳定性和性能,避免潜在的风险和故障。同时,不断学习和掌握内存管理的知识,也是有效预防内存泄漏的重要途径。
651 62
|
7月前
|
移动开发 运维 供应链
通过array.some()实现权限检查、表单验证、库存管理、内容审查和数据处理;js数组元素检查的方法,some()的使用详解,array.some与array.every的区别(附实际应用代码)
array.some()可以用来权限检查、表单验证、库存管理、内容审查和数据处理等数据校验工作,核心在于利用其短路机制,速度更快,节约性能。 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
7月前
|
供应链 JavaScript 前端开发
通过array.every()实现数据验证、权限检查和一致性检查;js数组元素检查的方法,every()的使用详解,array.some与array.every的区别(附实际应用代码)
array.every()可以用来数据验证、权限检查、一致性检查等数据校验工作,核心在于利用其短路机制,速度更快,节约性能。 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~