实现 padStart() 和 padEnd() 的 Polyfill
手写实现字符串填充方法 padStart 和 padEnd 的 polyfill,用于在字符串开头或末尾填充指定字符
问题
padStart() 和 padEnd() 是 ES2017 引入的字符串方法,用于在字符串的开头或末尾填充指定字符,直到字符串达到指定长度。在不支持这些方法的旧版浏览器中,我们需要实现 polyfill 来提供相同的功能。
这两个方法的作用:
padStart(targetLength, padString):从字符串开头填充padEnd(targetLength, padString):从字符串末尾填充
解答
// padStart polyfill
if (!String.prototype.padStart) {
String.prototype.padStart = function(targetLength, padString) {
// 将目标长度转换为整数
targetLength = targetLength >> 0;
// 获取当前字符串
let str = String(this);
// 如果目标长度小于等于当前字符串长度,直接返回原字符串
if (str.length >= targetLength) {
return str;
}
// 设置默认填充字符为空格
padString = String(typeof padString !== 'undefined' ? padString : ' ');
// 如果填充字符为空字符串,直接返回原字符串
if (padString === '') {
return str;
}
// 计算需要填充的长度
let padLength = targetLength - str.length;
// 重复填充字符串,直到长度足够
let repeatedPadString = '';
while (padLength > padString.length) {
repeatedPadString += padString;
padLength -= padString.length;
}
// 添加剩余需要的填充字符
repeatedPadString += padString.slice(0, padLength);
// 返回填充后的字符串
return repeatedPadString + str;
};
}
// padEnd polyfill
if (!String.prototype.padEnd) {
String.prototype.padEnd = function(targetLength, padString) {
// 将目标长度转换为整数
targetLength = targetLength >> 0;
// 获取当前字符串
let str = String(this);
// 如果目标长度小于等于当前字符串长度,直接返回原字符串
if (str.length >= targetLength) {
return str;
}
// 设置默认填充字符为空格
padString = String(typeof padString !== 'undefined' ? padString : ' ');
// 如果填充字符为空字符串,直接返回原字符串
if (padString === '') {
return str;
}
// 计算需要填充的长度
let padLength = targetLength - str.length;
// 重复填充字符串,直到长度足够
let repeatedPadString = '';
while (padLength > padString.length) {
repeatedPadString += padString;
padLength -= padString.length;
}
// 添加剩余需要的填充字符
repeatedPadString += padString.slice(0, padLength);
// 返回填充后的字符串
return str + repeatedPadString;
};
}
使用示例
// padStart 示例
console.log('5'.padStart(3, '0')); // "005"
console.log('hello'.padStart(10, '*')); // "*****hello"
console.log('abc'.padStart(10, '123')); // "1231231abc"
console.log('world'.padStart(3, '0')); // "world" (长度已够,不填充)
console.log('test'.padStart(8)); // " test" (默认用空格填充)
// padEnd 示例
console.log('5'.padEnd(3, '0')); // "500"
console.log('hello'.padEnd(10, '*')); // "hello*****"
console.log('abc'.padEnd(10, '123')); // "abc1231231"
console.log('world'.padEnd(3, '0')); // "world" (长度已够,不填充)
console.log('test'.padEnd(8)); // "test " (默认用空格填充)
// 实际应用场景
// 1. 格式化数字(补零)
const num = 7;
console.log(num.toString().padStart(2, '0')); // "07"
// 2. 对齐文本
const items = ['Apple', 'Banana', 'Cherry'];
items.forEach(item => {
console.log(item.padEnd(10, '.') + ' $5.00');
});
// Apple..... $5.00
// Banana.... $5.00
// Cherry.... $5.00
// 3. 格式化时间
const hour = '9';
const minute = '5';
console.log(`${hour.padStart(2, '0')}:${minute.padStart(2, '0')}`); // "09:05"
关键点
-
类型转换:使用
String(this)确保处理的是字符串类型,使用targetLength >> 0将目标长度转换为整数 -
边界条件处理:
- 当目标长度小于等于原字符串长度时,直接返回原字符串
- 当填充字符为空字符串时,直接返回原字符串
- 当 padString 未定义时,默认使用空格填充
-
填充字符串的构建:通过循环重复填充字符串,直到长度足够,最后使用
slice()截取需要的部分 -
padStart 和 padEnd 的区别:仅在最后拼接字符串时的顺序不同
- padStart:
repeatedPadString + str - padEnd:
str + repeatedPadString
- padStart:
-
性能优化:使用循环累加而不是
repeat()方法,因为repeat()本身也可能需要 polyfill -
兼容性检查:通过
if (!String.prototype.padStart)判断,避免覆盖原生实现
目录