es6入门总结(二)

es6入门总结(二)

摘抄自阮一峰ECMAScript6入门:http://es6.ruanyifeng.com/#docs/string

一、字符串的扩展
   1.unicode的改进、遍历器接口
   2.JSON.stringify()
   3.模板字符串
   4.标签模板
一、字符串的扩展
1.unicode的改进、遍历器接口
  • es6中允许采用 \uxxxx形式表示一个字符,其中xxxx表示字符的Unicode码点,只限于码点 \u0000~\uFFFF之间的字符,超出这个范围必须用两个双字节的形式表示。只要将码点放入大括号,就能正确解读该字符。
"\u0061" //"a"
"\uD842\uDFB7"//"?"
"\u20BB7"// 7 会理解为\u20BB+7,\u20BB是一个不可打印字符,会显示一个空格,后面跟一个7
"\u{20BB7}"//"?" 将码点放入大括号能够正确解读该字符
"\u{41}\u{42}\u{43}"//ABC
let hello = 123;
hell\u{6F} // 123
'\u{1F680}' === '\uD83D\uDE80'//true 大括号表示法与四字节的UTF-16编码是等价的
  • es6为字符串添加了遍历器接口,是的字符串可以被for…of循环遍历,最大的优点就是可以识别大于0xFFFF的码点,传统的for循环无法识别这样的码点
for (let codePoint of 'foo'){
  console.log(codePoint)
}
//"f"
//"o"
//"o"
let text = String.fromCodePoint(0x20BB7);
for(let i = 0;i<text.length;i++){
  console.log(text[i]);
}
//" "
//" " for循环都不可打印,会认为它包含两个字符
for(let i of text){
  console.log(i);
}
// "?" for....of循环会正确识别出这一字符
2.JSON.stringify()
JSON.stringify('\u{D834}')//"\u{D824}"
JSON.stringify('\uDF06\uD834')//""\\udf06\\ud834
//如果遇到 0xD800到 0xDFFF之间的单个码点。或者不存在的配对形式,会返回转义字符串,留给应用自己决定下一步的处理
3.模板字符串
  • 使用模板字符串使用反引号 `` 标识,可以当作普通字符串使用,也可以用来定义多行字符串,或者使用 ${} 在字符串中嵌入变量,大括号内部可以放入任意js表达式,可以进行计算,以及引用对象属性
$('#result').append(
  'There are <b>' + basket.count + '</b>' + 
  'items in your basket,' +
  '<em>' + basket.onSale +
  '</em> are on sale!                         '
)
//使用jq写法,繁琐不好写
$('#result').append(`
 There are <b>${basket.count}</b> items
 in your basket, <em>${basket.onSale}</em>
 are on sale!
`)
//使用模板字符串使用反引号` `标识,可以当作普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量
$('#list').html(`
<ul>
  <li>first</li>
  <li>second</li>
</ul>
`);
//使用模板字符串表示多行字符串,所有的空格和缩进都会被保留在输出之中,
$('#list').html(`
<ul>
  <li>first</li>
  <li>second</li>
</ul>
`.trim());//如果不想要换行,可以使用 trim()方法消除
function authorize(user,action){
  if(!user.hasPrivilege(action)){
    throw new Error(
    `User ${user.name} is not authorized to do ${action}`
    );
  }
}//嵌入变量,需要将变量名写在${}之中
let x = 1;
let y = 2;
`${x} + ${y} = ${x + y}`//"1+2 = 3"
`${x} + {y * 2} = ${x + y * 2}`//"1+4 = 5"
let obj = {x:1,y:2};
`${obj.x + obj.y}`//"3"
//{}内部可以放入任意js表达式,可以进行运算,以及引用对象属性

function fn(){
  return "Hello World";
}
`foo ${fn()} bar`//foo Hello Wrold bar
//可以调用函数,如果{}中不是字符串按照一般规则转为字符串,如:{}中是一个对象,将默认调用对象的toString方法,柏年两没有声明,将报错
const tmpl = addrs => `
 <table>
   ${addrs.map(addr => `
     <tr><td>addr.first</td></tr>
     <tr><td>addr.last</td></tr>
 `).join('')}
 </table>
`
//模板字符串之间可以嵌套

const data = [
  {first:'<Jane>',last:'Bond'},
  {first:'Lars',last:'<Croft>'},
];
console.log(tmpl(data))//模板字符串的变量之中又嵌入了另一个模板字符串
let func = (name) => `Hello ${name}!`;
func('Jack') //"Hello Jack!"
//需要引用模板字符串本身时,可以将模板字符串写成一个函数的返回值,执行这个函数
4.标签模板

模板字符串可以紧跟在一个函数名后面。该函数将被调用来处理这个模板字符串,被称为"标签模板"功能

alert`123`
//等同于
alert(123)
//标签模板不是模板。是函数调用的一种特殊形式。"标签"指的是函数,紧跟在后面的模板字符串就是参数
let a = 5;
let b = 10;
tag`Hello ${a + b } world ${a * b}`;
//等同于⬇⬇⬇⬇⬇
tag(['Hello','world',''],15,50);
//tag是一个函数,整个表达式的返回值就是tag函数处理模板字符串后的返回值 
  • 标签字符串的应用
  1. 过滤html字符串,防止用户输入恶意内容
let message = 
   SaferHTML`<P>${sender} has sent you a message</P>`;
   function SafeHTML(templateData){
     let s = templateData[0];
     for (let i =1;i<argument.length;i++){
       let arg = String(argument[i]);
       s += arg.replace(/&/g,"&amp;")
               .replace(/</g,"&lt;")
               .replace(/>/g,"&gt;");
       s += templateData[i];
    }
    return s;
  }
  let sender = '<script>alert("abc")</script>'//恶意代码
  let message = SaferHTML`<p>${sender} has sent you a message</p>`;
  message
  //saferHTML函数处理,里面的特殊字符都会被转义,sender变量是用户提供的。经过SaferHTML函数处理,里面的特殊字符都会被转义
  1. 多语言转换(国际化处理)
i18n`Welcome to ${siteName},you are visitor number ${visitorNumber}!`
//"欢迎访问xxx,您是第xxxx位访问者!"

let libraryHTML = hashTemplate`
 <ul>
   #for book in ${myBooks}
   <li><i>#{book.title}</i> by #{book.author}</li>
   #end
 </ul>
`;
//模板字符串本身并不能取代Mustache之类的模板库,没有条件判断和循环处理功能,可以通过标签函数自定义模板处理函数
  1. 可以使用标签模板,在js中嵌入其他语言
jsx`
  <div>
     <input
        ref='input'
        onChange='${this.handleChange}'
        defaultValue='${this.state.value}'
     />
     ${this.state.value}
  </div>
`
//通过jsx函数,将一个dom字符串转为React对象

tag`First line\nSecond line`
function tag(strings){
   console.log(string.raw[0]);
   //strings.raw[0]为"First line\\nSecond line"
   //输出 "First line\nSecond line"
}
//tag函数第一个参数是strings,raw属性也指向一个数组,数组成员与strings数组一致,两者唯一的区别就是字符串里的斜杠都被转义了,strings.raw数组会将\n视为\\和n两个字符,而不是换行符。
  1. 标签模板可以嵌入其他语言但是模板字符串中不可以嵌入其他语言,默认会将字符串转义,会报错。
function tag(strs){
  strs[0] === undefined
  strs.raw[0] === "\\unicode and \\u{55}";
}
tag`\unicode and \u{55}`
//ES2018中放松了对标签模板里面的字符串转义的限制,如果遇到不合法的字符串转义就返回undefined,并且raw属性上可以得到原始字符串

let bad = `bad escape sequence: \unicode`;//报错
//只在标签模板解析字符串时有效,不是标签模板依然会报错
二、字符串的新增方法
1.String.fromCodePoint()
2.String.raw()
3. 实例方法:codePointAt()
4. 实例方法:normalize()
5. 实例方法:repeat()
6. 实例方法:padStart(),padEnd()
7. 实例方法:trimStart(),trimEnd()
  • String.fromCodePoint()( 弥补了es5中String.formCharCode()方法不能识别码点大于0xFFFF的字符,如果有多个参数,会把他们合并成一个字符串返回,fromCodePoint方法定义在String对象上,CodePointAt方法定义在字符串的实例对象上 )
String.fromCodePoint(0x20BB7)
// "?"
String.fromCodePoint(0x78,0x1f680,0x79) === 'x\uD83D\uDE80y'
//true
  • String.raw() 为原生对象提供了一个raw()方法。该方法返回一个斜杠都被转义(即斜杠前面再加一个斜杠)的字符串,往往用于模板字符串的处理
String.raw`Hi\n${2+3}!`
//实际返回"Hi\\n5",显示的是转义后的结果"Hi\n5!"
String.raw`Hi\u000A!`;
//实际返回"Hi\\u000A!",显示的是转义后的结果"Hi\u000A!"
String.raw`Hi\\n`
//返回"Hi\\\\n"
String.raw`Hi\\n` === "Hi\\\n"//true
//如果原字符串的斜杠已经转义,那么String.raw()会进行再次转义
String.raw({raw:['foo','bar']},1 + 2)//"foo3bar"
//等同于⬆⬆⬆⬆⬆⬆⬆⬆⬆ `foo${1 + 2}bar`,String.raw()方法的第一个参数是一个对象,它的raw属性等同于原始的模板字符串解析后得到的数组
String.raw = function(string,...values){
   let output = '';
   let index;
   for(index = 0;index < values.length;index++){
     output += strings.raw[index] + values[index];
  }
  output += strings.raw[index]
  return output;
}
  • codePointAt() 是测试一个字符由两个字节还是四个字节组成的最简单的办法。能够正确处理4个字节储存的字符,返回一个字符的码点,参数是字符在字符串上的位置(从0开始),返回的是码点的十进制。
let s = '?a';
s.codePointAt(0) // 134071
s.codePointAt(2) //97
s.codePointAt(2).toString(16) //"61" 想要是用十六进制可以使用toString()方法转换
for (let ch of s){
  console.log(ch.codePointAt(0).toString(16));
}
//20bb7
//61
//使用for...of循环会正确的识别32位UTF-16字符

let arr = [...'?a'];
arr.forEach(
  ch => console.log(ch.codePointAt(0).toString(16))
);
//20bb7
//61
//可以使用扩展运算符(...)进行展开运算
function is32Bit(c){
  return c.codePointAt(0) > 0xFFFF;
}
is32Bit("?")//true
is32Bit("a")//false
//测试一个字符串由两个字节还是由四个字节组成的最简单的方法
  • ==normalize()==用来将不同表示方法统一为同样的形式(但目前不能识别三个火三个以上字符的合成,这种情况下只能通过正则表达式,通过Unicode编号区间判断)
normalize()默认参数内容
NFC默认参数,表示"标准等价合成",返回多个简单字符的合成字符。值得是视觉和语义上的等价
NFD表示"标准等价分解",即在标准等价的前提下,返回合成字符分解的多个简单字符。
NFKC表示"兼容等价合成",返回字符串,指的是语义上的等价
NFKD表示"兼容等价分解",在兼容等价的前提下,返回合成字符分解的多个简单字符
  • 实例方法:repeat() ;repeat方法返回一个新字符串,表示将原字符重复n次;参数如果是小数会被取整,如果是负数或者Infinity,会报错,NaN为0,参数是字符串会先转换成数字。
'x'.repeat(3)//"xxx"
'hello'.repeat(2)//"hellohello"
'na'.repeat(0)//""
//返回新的字符串,将原字符串重复参数次
'na'.repeat(Infinity)//RangeError
'na'.repeat(-1)//RangeError
//参数是负数或者Infinity,会报错
'na'.repeat(2.9)//"nana"
//参数如果是小数,会被取整
'na'.repeat(-0.9)//""
//如果参数是0到-1之间的小数,则等同于0
'na'.repeat(NaN)//""
//NaN等同于0
'na'.repeat('na')//""
'na'.repeat('3')//"nanana"
//如果参数是字符串则会先转成数字
  • 实例方法:padStart(),padEnd(),es7中引入了字符串补全长度的功能,如果某个字符串不够指定长度,会在头部或尾部补全。padStart()用于头部补全padEnd()用于尾部补全。一共接收两个参数,第一个参数是字符串补全生效的最大长度,第二个参数是用来补全字符串,为数值补全指定位数,提示字符串格式
'x'.padStart(5,'ab')//'ababx'
'x'.padStart(5,'ab')//'abax'
//padStart()用于头部补全,第一个参数是字符串补全生效的最大长度,第二个参数是用来补全的字符串
'x'.padEnd(5,'ab')//'xabab'
'x'.padEnd(4,'ab')//'xaba'
//padEnd()用于尾部补全,参数同上⬆⬆⬆⬆⬆⬆
'xxx'.padStart(2,'ab')//'xxx'
'xxx'.padEnd(2,'ab')//'xxx'
//如果补全长度小于原字符串长度,则返回原字符串
'abc'.padStart(7,'1234567')//'1234abc'
//如果原字符串加上补全字符串的长度大于最大长度,则会截去超出位数的补全字符串
'x'.padStart(4)//'   x'
'x'.padEnd(4)//'x   '
//如果省略第二个参数默认使用空格补全长度
'x'.padStart(5,'0')//0000x
'12'.padStart(5,'0')//00012
'123'.padStart(5,'0')//00123
//最常用的方法是数值补全指定位数
'12'.padStart(10,'YYYY-MM-DD')//"YYYY-MM-12"
'09-12'.padStart(10,'YYYY-MM-DD')//"YYYY-09-12"
  • 实例方法:trimStart(),trimEnd();es9中新增了trimStart()和trimEnd(),trimStart()消除头部空格,trimEnd()消除尾部空格,都是返回新字符串,不会修改原始字符串。
const s = '  abc  ';
s.trim()//"abc"
s.trimStart()//"abc  "
s.trimEnd()//"  abc"
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值