js 字符串方法
2020-02-03 本文已影响0人
Super曲江龙Kimi
1.字符串模板
let x = 1;
let y = 2;
`${x} + ${y} = ${x + y}`
经过babel的转换后
var x = 1;
var y = 2;
x + " + " + y + " = " + (x + y);
其实原理就是字符串拼接。所以如果${}中不是字符串,则会类型转换成字符串
`foo ${{}} bar`
// "foo [object Object] bar"
标签模板
let a = 5;
let b = 10;
tag`Hello ${ a + b } world ${ a * b }`;
// 等同于 tag(['Hello ', ' world ', ''], 15, 50);
function tag(stringArr, ...values){
// ...
}
标签模板更多的是用来自定义拼接规则的。
2.字符串新增方法
(1)includes startsWith endsWith
let s = 'Hello world!';
s.startsWith('Hello') // true
s.endsWith('!') // true
s.includes('o') // true
第二个参数表示开始的位置
s.startsWith('world', 6) // true 从第6位开始搜索
s.endsWith('Hello', 5) // true 只有前五位
s.includes('Hello', 6) // false 从第6位开始搜索
手写startsWith、endsWite、includes
v8 js源码中的startsWith
function StringEndsWith(searchString, position) { // length == 1
CHECK_OBJECT_COERCIBLE(this, "String.prototype.endsWith");
var s = TO_STRING(this);
if (IsRegExp(searchString)) {
throw %make_type_error(kFirstArgumentNotRegExp, "String.prototype.endsWith");
}
var ss = TO_STRING(searchString);
var s_len = s.length;
var pos = !IS_UNDEFINED(position) ? TO_INTEGER(position) : s_len
var end = MinSimple(MaxSimple(pos, 0), s_len);
var ss_len = ss.length;
var start = end - ss_len;
if (start < 0) {
return false;
}
return %_SubString(s, start, start + ss_len) === ss;
}
// Polyfill
String.prototype.startsWith= function(search, pos) {
pos = !pos || pos < 0 ? 0 : +pos;
return this.substring(pos, pos + search.length) === search;
}
String.prototype.endsWith = function(search, this_len) {
if (this_len === undefined || this_len > this.length) {
this_len = this.length;
}
return this.substring(this_len - search.length, this_len) === search;
};
includes
function StringIncludes(searchString, position) { // length == 1
CHECK_OBJECT_COERCIBLE(this, "String.prototype.includes");
var string = TO_STRING(this);
if (IsRegExp(searchString)) {
throw %make_type_error(kFirstArgumentNotRegExp, "String.prototype.includes");
}
searchString = TO_STRING(searchString);
var pos = TO_INTEGER(position);
var stringLength = string.length;
if (pos < 0) pos = 0;
if (pos > stringLength) pos = stringLength;
var searchStringLength = searchString.length;
if (searchStringLength + pos > stringLength) {
return false;
}
return %StringIndexOf(string, searchString, pos) !== -1;
}
(2)repeat
repeat方法返回一个新字符串,表示将原字符串重复n次。
'x'.repeat(3) // "xxx"
'hello'.repeat(2) // "hellohello"
'na'.repeat(0) // ""
'na'.repeat(2.9) // "nana"
'na'.repeat(-0.9) // ""
'na'.repeat(NaN) // ""
'na'.repeat('na') // ""
'na'.repeat('3') // "nanana"
如果repeat的参数是负数或者Infinity,会报错。
'na'.repeat(Infinity)
// RangeError
'na'.repeat(-1)
// RangeError
v8 js源码中的repeat
function StringRepeat(count) {
CHECK_OBJECT_COERCIBLE(this, "String.prototype.repeat");
var s = TO_STRING(this);
var n = TO_INTEGER(count);
if (n < 0 || n === INFINITY) throw %make_range_error(kInvalidCountValue);
// Early return to allow an arbitrarily-large repeat of the empty string.
if (s.length === 0) return "";
// The maximum string length is stored in a smi, so a longer repeat
// must result in a range error.
if (n > %_MaxSmi()) throw %make_range_error(kInvalidCountValue);
var r = "";
while (true) {
if (n & 1) r += s;
n >>= 1;
if (n === 0) return r;
s += s;
}
}
(3) fromCodePoint() fromCharCode()
fromCharCode不能识别码点大于0xFFFF的字符。需要使用fromCodePoint
String.fromCharCode(0x61,0x62,0x63) // abc
String.fromCharCode(0x20BB7) // 乱码
String.fromCodePoint(0x20BB7) // 𠮷
(4) codePointAt() charCodeAt() charAt()
同样charCodeAt无法识别大于0xFFFF的字符 需要使用codePointAt
const str = "𠮷";
const str1 = "吉";
console.log(str.length,str1.length) // 2 1
console.log(str.charAt(0),str.charAt(1),str1.charAt(0),str1.charAt(1)) // 乱码 乱码 "吉" ""
// charCodeAt如果传入负数或超出范围的值则返回NaN ,codePointAt返回undefined
console.log(str.charCodeAt(0),str.charCodeAt(1),str1.charCodeAt(),str1.charCodeAt(1)) // 55362 57271 21513 NaN
console.log(str.codePointAt(),str.codePointAt(1),str1.codePointAt(0),str1.codePointAt(1)) // 134071 57271 21513 undefined