为了账号安全,请及时绑定邮箱和手机立即绑定

深入ES6 四 字符串的括展

标签:
JavaScript
第四章 字符串的括展

ES6加强了对Unicode的支持,并且扩展了字符串对象。本章把重点放在ES6对对象方法的括展上,至于字符Unicode表示法的加强,则不打算详细展开。本章主要包括:

  1. 模板字符串与标签模板
  2. 字符串括展方法
  3. 字符的Unicode表示法(简介)
4.1模板字符串与模板标签

模板字符串

在第一章我们已经大体介绍了模板字符串的使用方法,先让我们回顾一下。

使用模板字符串可以轻松的在字符串中进行变量的替换。注意使用模板时,最外层为``号(反引号),变量使用${}包裹。${}的花括号中可以是任意表达式。如果表达式的返回值不是字符串,则将按照一般规则转化为字符串。比如如果大括号中是一个对象的话,将默认调用对象的toString方法。

let name = 'Kyle';
let foo = `学生${name}正在学习ES6`;

再比如:

let student = {
    name : 'Kyle',
    toString: function () {
        return 'Agent' + this.name
    }
};
let foo = `学生${student}正在学习ES6`;
console.log(foo); // 输出:学生AgentKyle正在学习ES6

这解决了ES5中换行和引入变量琐碎不便的问题。下面是一个使用模板字符串拼接和普通字符串拼接DOM并插入到页面的例子,你可以明显的发现前者要方便很多:

let arr = ['first', 'second', 'third'];

let ul = `<ul>
            <li>${arr[0]}</li>
            <li>${arr[1]}</li>
            <li>${arr[2]}</li>
         </ul>`;

let normalUl = '<ul>\
                    <li>'+arr[0]+'</li>\
                    <li>'+arr[1]+'</li>\
                    <li>'+arr[2]+'</li>\
                </ul>';

document.getElementById('container').innerHTML = ul;
document.getElementById('normal-container').innerHTML = normalUl;

上面的代码使用的两种方式呈现的最终效果是一致的,但现在我们稍作修改,把下面的两个innerHTML改为innerText,运行结果:

如果使用模板字符串表示多行字符串,所有的空格和缩进会被保留在输出中。查看源码可以发现,浏览器在处理时使用了br标签。

标签模板

标签模板其实并非模板,而是一种函数的调用方式。标签其实就是一个函数,其格式是:

标签函数`模板字符串`

其中标签函数会被默认注入若干个参数,第一个参数是一个数组,其中的元素是模板字符串非变量与变量之间的各个部分,随后的参数是模板字符串中的变量被替换后的值。显然,如果模板字符串中有n个变量,标签函数就会有n+1个参数。这可能听起来有些抽象,我们看下面的例子就一目了然了:

let student = {
    id:'2014556698',
    name:'AgentKyle'
};

function tagFun(arr, ...args) {
    arr.forEach((item) => {
        console.log(item);
    });

    args.forEach((item) => {
        console.log(item);
    })

    return 'ok!'
}

tagFun`学生姓名:${student.name},学生id:${student.id};`;  // =>ok!

运行结果,控制台输出:

学生姓名:
,学生id:
;
2014556698
AgentKyle

需要注意标签函数第一个参数数组的最后一个元素,它始终表示最后一个变量到模板字符串末尾的部分,在上面的例子中,这部分有一个;(分号)。但如果这部分什么也没有,模板就结束了,则其最后一个元素将会是''(空)。模板标签表达式的最终返回值即标签函数的返回值。

下面的标签函数可以返回像不使用模板标签那样的填充模板:

function tagFun() {

    let str = '',
        strArr = arguments[0];

    for(let i = 0; i<strArr.length; i++){
        str+=strArr[i];
        str+=arguments[i+1]||''
    }

    return str;
}

引入标签模板的一个目的在于对模板字符串本身进行更灵活的控制,例如去除容易引起安全问题的危险字符,对模板字符进行国际化等等。

此外,你可以使用模板标签在JS语言中嵌入其他语言:

jsx`
<input ref="input" onchange=${this.handleChange} >
`

上面通过jsx函数将一个DOM字符串转成了React对象。你可以在github上找到jsx函数的源码。

此外,标签函数的第一个参数还具有一个row属性,它是一个和其宿主数组几乎一模一样的数组,唯一的区别在于其中的字符串元素的反斜线都被转译(前面加了一个\)了。String构造器也原生提供了String.row静态方法,用来生成一个反斜线都被转译的字符串:

String.row`hello world\n${1+1}` // => hello world\\n2
String.row'\u000A!' // => \\u000A 
4.2 字符串的扩展方法

includes,startsWith,endsWith

ES5中,当我们试着判断一个字符串片段是否包含在另一个字符串时,一般会考虑使用IndexOf的方式:

"But those who wait for the Lord will renew their strength".indexOf('shall') // =>-1

当其匹配成功时,会返回匹配到的位置。若是不存在,则会返回-1。这固然很好,但问题是有的时候我们只不过是想知道A串是否包含在B串内,并不想知道它在哪里。而且匹配失败时返回-1的特性无形中增加了编码量以及出错的概率:

var flag = "But those who wait for the Lord will renew their strength".indexOf('shall') 
if(flag === -1){}
if(flag){} // 容易出错的逻辑,这样其实是指的从字符串首匹配成功就不执行里面的代码片段

ES6中提供了三中新方法:

  1. includes() :返回布尔值,表示是否找到了字符串
  2. startsWith():返回布尔值,表示参数字符串是否在源字符串的开头
  3. endsWith():返回布尔值,表示参数字符串是否在源字符串的尾部

它们都可以接受第二个参数以控制查找的范围,但endsWith与其它的方法行为不同,其它两个方法都是从规定的索引一直到字符串最后进行匹配,而endsWith则是从字符串的开头到规定的索引的中间段进行查找。下面是一些例子:

let str = "But those who wait for the Lord will renew their strength";
console.log(str.includes('will')); //t
console.log(str.includes('will',40)); //f
console.log(str.startsWith('But'));//t
console.log(str.startsWith('but')); //f 匹配区分大小写
console.log(str.startsWith('those',4)); // t 注意这里是4,而并非5,因为包含开头索引的位置
console.log(str.endsWith('those')); // f
console.log(str.endsWith('those',9)); // t 注意这里是9,而不是8,因为不包含最后索引的位置

注意,所有的索引都是只包含开头索引的位置,不包含结束索引的位置

repeat

有时我们想将一个字符串复制累加n次:

let str = 'hello';
let repeatedStr = function (n) {
    let newStr = '';
    for (let i = 0; n < 5; i++) {
        newStr+=str;
    }
    return newStr;
}(5);
console.log(repeatedStr);

ES6提供了原生的解决方案:

let repeatedStr = str.repeat(5);

它接收一个数值型参数,如果传入一个小数,则会向下取整;0到-1之间的小数,取整后等价于-0,即0;如果传入一个字符串类型的数,则会先转换成数值类型再进行计算。参数NaN等价于0。

如果其参数是非0到-1之间负数或Infinity,则会报错。

4.3 字符的Unicode表示法

详见阮一峰大神的ES6教程

点击查看更多内容
7人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
Web前端工程师
手记
粉丝
316
获赞与收藏
3231

关注作者,订阅最新文章

阅读免费教程

感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消