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
上一篇下一篇

猜你喜欢

热点阅读