「本文已参与好文召集令活动,点击查看:后端、大前端双赛道投稿,2万元奖池等你挑战!」
首先要提一下 String.fromCharCode() ,两个方法用途都是将unicode码转为对应的文字。但是String.fromCodePoint()是对String.fromCharCode()的改进。
方法名 | js版本 | 区别 |
---|---|---|
formCharCode | es5 | 不能识别大于0xFFFF的码点,会发生溢出。fromCodePoint与之相反 |
formCodePoint | es6 | 当传入多个参数时,他们会被合成一个字符串返回,fromCharCode则不会 |
// 验证1:0x20BB7 大于 0xFFFF 未呗识别
String.fromCharCode(0x20BB7); // "ஷ"
String.fromCodePoint(0x20BB7); // "𠮷"
String.fromCodePoint(0xFFFF); // ""
String.fromCharCode(0xFFFF); // ""
// 验证2:多个参数是否合并成一个字符串返回
String.fromCodePoint(0x78, 0x1f680, 0x79) === 'x\uD83D\uDE80y' // true
String.fromCharCode(0x78, 0x1f680, 0x79) === 'x\uD83D\uDE80y' // false
两种用法:
将转义字符前加一个斜杠
String.raw`Hi\n${2+3}` \\ "Hi\\5"
String.raw`Hi\u000A!` \\ "Hi\\u000A!"
如果原字符串的斜杠已经被转义 即( \n )
String.raw`Hi\\n`; \\ "Hi\\\\n"
String.raw`Hi\\n` == "Hi\\\\n"; \\ true
正常来说,这种方法很少使用,但是为了模拟 t${0}e${1}s${2}t
String.raw({raw:'test'},3,4,5) // "t3e4s5t"
String.raw({raw:['aa','bb','cc'],1+2,3}) // "aa3bb3cc"
// 下面这个函数和 `aa${2 + 3}bb${'Java' + 'Script'}cc` 是相等的.
String.raw({raw:['aa','bb','cc']},2+3,'java'+'Script') // aa5bbjavaScriptcc
String.raw = function (strings, ...values) {
let output = '';
let index;
for (index = 0; index < values.length; index++) {
output += strings.raw[index] + values[index];
}
output += strings.raw[index]
return output;
}
首先要说一下什么是实例方法,有可能是我还是个菜鸡,所以刚一听到实例方法不知道它是什么。 js的方法类型有:实例方法、静态方法、原型方法三种。
实例方法要用到function这个对象中的prototype属性来定义。实例化对象后才可以使用
function A (){}
A.prototype.sayHello = function(){
console.log("Hello")
}
var a = new A();
a.sayHello(); // Hello
只通过A.方法 就能调用
function A(){}
A.sayHello = function(){
console.log("Hello")
}
A.sayHello(); //Hello
原型中的方法实例和构造函数都可以访问到
function A(){}
A.prototype.sayHello = function(){
console.log("原型方法")
}
A.sayHello = function(){
console.log("静态方法")
}
A.sayHello() // "静态方法"
A.prototype.sayHello() // "原型方法"
let a = new A();
a.sayHello(); // "原型方法"
函数是一个对象,函数对象中的属性 prototype可以想成一个指针,指向一个方法(这样不用每一次用构造函数创造一个新实例后都要将方法重新创建一遍)。这样就好理解了,var a是A的一个引用,也就是指针,a就可以指向sayHello这个方法,如果直接A.sayHello()是会报错的,因为A不是一个指针,a.sayHello()也会报错,因为a不是一个方法对象。
言归正传 codePointAt()的出现是为了解决Unicode码点大于0xFFFF的字符无法读取整个字符的问题
var s = "𠮷";
s.length // 2 字符串长度会误判为2
// 返回了两个字符的 十进制码点
s.charCodeAt(0) // 55362
s.charCodeAt(1) // 57271
//返回了它的十进制码点 134071(即十六进制的20BB7)
s.charPointAt(0) // 134071
s.charPointAt(1) // 57271
将十进制码点转为十六进制
s.codePointAt(0).toString(16) // "20bb7"
codePointAt()方法是测试一个字符由两个字节还是由四个字节组成的最简单方法
function is32Bit(c) {
return c.codePointAt(0) > 0xFFFF;
}
is32Bit("𠮷") // true
is32Bit("a") // false
许多欧洲语言有语调符号和重音符号 Unicode提供了两种方法:
'\u01D1'==='\u004F\u030C' //false
'\u01D1'.length // 1
'\u004F\u030C'.length // 2
上面代码 javaScript不能识别他们是一样的
但是 normalize()方法会将Unicode正视化
'\u01D1'.normalize() === '\u004F\u030C'.normalize() // true
'\u004F\u030C'.normalize('NFC').length // 1
'\u004F\u030C'.normalize('NFD').length // 2
上面代码表示,NFC参数返回字符的合成形式,NFD参数返回字符的分解形式。
不过,normalize方法目前不能识别三个或三个以上字符的合成。这种情况下,还是只能使用正则表达式,通过 Unicode 编号区间判断。
作用:用来确定一个字符串是否包含在另一个字符串中
let a ="abcd";
a.indexOf("b"); // 1
a.indexOf("e"); // -1
a.includes("b"); // true
a.includes("f"); // false
let a = "abc";
a.startsWith("a"); // true
a.startsWith("b"); // false
a.endsWith("c"); // true
a.endsWith("a"); // false
startsWith()、endsWith()、includes() 都有第二个参数,表示搜索的起始位置。
let s = 'Hello world!';
s.startsWith('world', 6) // true
s.endsWith('Hello', 5) // true
s.includes('Hello', 6) // false
作用:返回一个新字符串,表示将原字符串重复多次
"x".repeat(3); // "xxx"
"hello".repeat(2); // "hellohello"
"x".repeat(0) // ""
"x".repeat(2.5). // "xx"
"x".repeat(-1) // RangeError
"x".repeat(Infinity) // RangeError
"x".repeat(-0.3) // ""
"x".repeat(NaN) // ""
"x".repeat("2") // "xx"
用于补全字符串,padStart()用于补全头部。padEnd()用于尾部补全。
两个参数:
'xxx'.padStart(5,"abc"); // "abxxx"
'xxx'.padEnd(5,"abc"); // "xxxab"
'xxx'.padStart(2,'ab') // "xxx"
'xxx'.padEnd(2,'ab') // "xxx"
'abc'.padStart(10, '0123456789') // "0123456abc"
省略第二个参数,默认使用空格补全
'x'.padStart(4) // ' x'
'x'.padEnd(4) // 'x '
'1'.padStart(10,'0') // "0000000001"
'123456'.padStart(10, '0') // "0000123456"
'12'.padStart(10,'YYYY-MM-DD') // "YYYY-MM-12"
'09-12'.padStart(10, 'YYYY-MM-DD') // "YYYY-09-12"
const s = ' abc ';
s.trim() // "abc"
s.trimStart() // "abc "
s.trimEnd() // " abc"
浏览器还部署了额外的两个方法,trimLeft()是trimStart()的别名,trimRight()是trimEnd()的别名。这两个用法与trimStart()和trimEnd()相同。
只能替换第一个匹配
'aabbcc'.replace('b','_') // aa_bcc
要想替换所有 b ,需要使用 /g 修饰符
'aabbcc'.replace(/b/g, '_') // 'aa__cc'
'aabbcc'.replaceAll('b', '_') // "aa__cc"
// 不报错
'aabbcc'.replace(/b/, '_')
// 报错
'aabbcc'.replaceAll(/b/, '_')
// $& 表示匹配的字符串,即`b`本身
// 所以返回结果与原字符串一致
'abbc'.replaceAll('b', '$&')
// 'abbc'
// $` 表示匹配结果之前的字符串
// 对于第一个`b`,$` 指代`a`
// 对于第二个`b`,$` 指代`ab`
'abbc'.replaceAll('b', '$`')
// 'aaabc'
// $' 表示匹配结果之后的字符串
// 对于第一个`b`,$' 指代`bc`
// 对于第二个`b`,$' 指代`c`
'abbc'.replaceAll('b', `$'`)
// 'abccc'
// $1 表示正则表达式的第一个组匹配,指代`ab`
// $2 表示正则表达式的第二个组匹配,指代`bc`
'abbc'.replaceAll(/(ab)(bc)/g, '$2$1')
// 'bcab'
// $$ 指代 $
'abc'.replaceAll('b', '$$')
// 'a$c'
'aabbcc'.replaceAll('b', () => '_') // 'aa__cc'