ES6精华:字符串扩展

2018-06-13 admin

1 四字节字符

ES6大幅增强了对4字节(32位)字符的支持。

JS内部使用UTF-16编码规则(网页通常为UTF-8)。 1字符固定为2字节,1字节为8位(二进制),其码点小于0xFFFF。 有些符号的码点大于0xFFFF,需4字节表示,即常说的32位UTF-16字符。

1.1 表示方法

新增一种表示字符的方法:\u{20BB7}。 用{}将码点括起,使其可直接表示超过0xFFFF的值。

let str1 = '𠮷'; // 非吉,虽也读作 jí 。
let str2 = '\u{20BB7}';
let str3 = '\uD842\uDFB7';

console.log(str1 === str2); // true
console.log(str2 === str3); // true

4字节字符的两种表示有固定的转化规则,不是简单的相加。

let c = 0x20BB7;
let ch = 0xD842;
let cl = 0xDFB7;

console.log( H(Number(c)) === ch ); // true
console.log( L(Number(c)) === cl ); // true

function H(c) {
  return Math.floor((c - 0x10000) / 0x400) + 0xD800;
}
function L(c) {
  return (c - 0x10000) % 0x400 + 0xDC00;
}

1.2 codePoint 系列

codePointAt & charCodeAt 使用.codePointAt(0)正确读取到完整的4字节字符。

let str = '𠮷';

console.log( str.charCodeAt(0) ); // 55362,即 \uD842 。
console.log( str.charCodeAt(1) ); // 57271,即 \uDFB7 。
console.log( str.codePointAt(0) ); // 134071,即 \u{20BB7} ,即 𠮷。
console.log( str.codePointAt(1) ); // 57271,即 \uDFB7 。

fromCodePoint & fromCharCode 使用String.fromCodePoint()正确读取大于0xFFFF的32位字符的码点。

console.log( String.fromCharCode(0x20BB7) ); // 解析不成功,已超过 0xFFFF 。
console.log( String.fromCodePoint(0x20BB7) ); // '𠮷',即'\u{20BB7}'。

console.log( String.fromCharCode(0xD842) + String.fromCharCode(0xDFB7) ); // '𠮷',即 '\uD842\uDFB7' 。
console.log( String.fromCodePoint(0xD842) + String.fromCodePoint(0xDFB7) ); // '𠮷',即 '\uD842\uDFB7' 。

1.3 常用方法集

判断是否为32位字符

console.log(is32Bit('a')); // false
console.log(is32Bit('𠮷')); // true

function is32Bit(s) {
  return s.codePointAt(0) > 0xFFFF;
}

获取正确的字符长度

let str = 'a𠮷b';

console.log( getStringLength1(str) ); // 3
console.log( getStringLength2(str) ); // 3

function getStringLength1(str) {
  let res = str.match(/[\s\S]/gu);
  return res ? res.length : 0;
}
function getStringLength2(str) {
  let res = 0;
  for (let c of str) { res++; } // 此遍历方法可以正确的识别32位字符。
  return res;
}

遍历方法 ES5由于不能正确的识别32位字符,遍历存在隐患。 ES6可以配合for ofcodePointAt更为正确的遍历字符串。

依次打印出:a 𠮷 b。

let str = 'a𠮷b';
for (let c of str) {
  console.log( String.fromCodePoint( c.codePointAt(0) ) );
}

2 模板字符串

在现行项目中,一般推荐使用模板字符串代替单双引号作为定义字符串的统一规范。

模板字符串是ES6新增的定义字符串的方式,使用替代''""。 其字符串中的空格、缩进和换行等空白字符都会被保留在输出之中。 其字符串中可以使用${}包裹有待执行的任意JS代码,包括另一个模板字符串。

let name = 'Wmaker';
let str = `
<div class="header">
  <p>My name is ${ name }.</p>
</div>
`;

console.log(str);
// 输出:
// 
// <div class="header">
//   <p>My name is Wmaker.</p>
// </div>

2.1 标签模板

标签模板是函数调用的一种特殊形式: fnstring`` 。

实际传入fn的参数有三类。 一是模板字符串会以/${([\s\S]+?)}/g为分隔符,拆分形成第一个参数。 二是将各个${}(输出变量)作为依次的参数。 三是第一个参数中的raw属性,这个稍后分析。

let words = 'hi';
let name = 'Wmaker';

say`Say ${words} to ${name}`;
// --- 等价于
say.apply(null, [
  ['Say ', ' to ', ''],
  'hi',
  'Wmaker'
]);

function say() {
  console.log(arguments);
}

raw属性 其是为了方便取得转义之前的原始模板而设计的。 其是与第一个参数基本相同,只不过里面的项都是转义之前的(相当再次转义)。

fn`1\n2`;
// --- 等价
fn.apply(null, ['1↵2', raw:['1\n2']]);

实际应用 标签模板的优势在于,不同场景不同参数都可使用同一编译模式。

let words = 'hi';
let name = 'Wmaker';

compileTemplate`<p>Say ${words} to ${name}.</p>`; // &lt;p&gt;Say hi to Wmaker.&lt;/p&gt;
compileTemplate`<p>Hi ${name}!</p>`; // &lt;p&gt;Hi Wmaker!&lt;/p&gt;

function compileTemplate() {
  let strs = arguments[0];
  let vars = Array.prototype.slice.call(arguments, 1);
  let res = transformHTML(strs[0]);

  vars.forEach((item, i) => {
    res += item + transformHTML(strs[i+1]);
  });

  console.log(res);

  function transformHTML(s) {
    return s.replace(/&/g, "&amp;")
      .replace(/</g, "&lt;")
      .replace(/>/g, "&gt;");
  }
}

3 新增函数

这里只列举一些常用的方法和方式,具体可看:String API

3.1 normalize()

方法会按照一种指定的Unicode正规形式将当前字符串正规化。 有些字符有两种不同的表示方法,而且其表示不等价,虽然在结果上等价。 比如有些语言有语调符号和重音符号Ǒ,可以使用带重音符号的字符和原字符与重音符两种表示方法。

let s1 = '\u01D1'; // 'Ǒ'
let s2 = '\u004F\u030C'; // 'Ǒ'

console.log(s1 === s2); // false
console.log(s1.normalize() === s2.normalize()); // true

3.2 padStart() & padEnd()

从头/尾部补全字符的长度,对填充物的态度是多则重复少则裁剪。

为数值补全指定位数。
'1'.padStart(5, '0'); // "00001"

提示字符串格式。
'12'.padStart(10, 'YYYY-MM-DD'); // "YYYY-MM-12"

3.3 String.raw()

用来充当模板字符串的处理函数,返回一个斜杠都被转义且变量已被替换的字符串。

let name = 'Wmaker';
let str = String.raw`
<div class=\"header\">
  <h2>${name}</h2>
</div>
`;

console.log(str);
// 输出:
// 
// <div class=\"header\">
//   <h2>Wmaker</h2>
// </div>

原文链接:https://segmentfault.com/a/1190000015271030

本站文章除注明转载外,均为本站原创或编译。欢迎任何形式的转载,但请务必注明出处。

转载请注明:文章转载自 JavaScript中文网 [https://www.javascriptcn.com]

本文地址:https://www.javascriptcn.com/read-33925.html

文章标题:ES6精华:字符串扩展

相关文章
JavaScript中字符串分割函数split用法实例
本文实例讲述了JavaScript中字符串分割函数split用法。分享给大家供大家参考。具体如下: 先来看下面这段代码: &lt;script type=&quot;text&#x2F;javascript&quot;&gt; var st...
2017-03-22
js使用split函数按照多个字符对字符串进行分割的方法
本文实例讲述了js使用split函数按照多个字符对字符串进行分割的方法。分享给大家供大家参考。具体分析如下: js中的split()函数可以对字符串按照指定的符号进行分割,但是如果字符串中存在多个分割符号,js的split()函数是否还可以...
2017-03-21
canvas图片绘制跨域问题解决方案Tainted canvases may not be exported
图片跨域问题的一般解决方法 当使用canvas绘制网络图片的时候,经常会出现“Tainted canvases may not be exported”报错,上网搜一下解决方案,应该给的都是给img添加crossOrigin属性,尝试了一下...
2018-04-19
IE7浏览器窗口大小改变事件执行多次bug及IE6/IE7/IE8下resize问题
本文主要通过代码示例给大家介绍IE7浏览器窗口大小改变事件执行多次bug及IE6/IE7/IE8下resize问题;分步介绍,先给大家介绍IE7浏览器窗口大小改变事件执行多次bug,具体问题分析及解决方案请看下文。 var resizeTi...
2017-03-29
详解JavaScript ES6中的Generator
今天讨论的新特性让我非常兴奋,因为这个特性是 ES6 中最神奇的特性。 这里的“神奇”意味着什么呢?对于初学者来说,该特性与以往的 JS 完全不同,甚至有些晦涩难懂。从某种意义上说,它完全改变了这门语言的通常行为,这不是“神奇”是什么呢。 ...
2017-03-27
localResizeIMG先压缩后使用ajax无刷新上传(移动端)
下面通过文字说明和代码分析的方式给大家分享移动端图片上传之localResizeIMG先压缩后ajax无刷新上传,具体实现过程请看下文。 现在科技太发达,移动设备像素越来越高,随便一张照片2M+,但是要做移动端图片上传和pc上略有不同,移动...
2017-03-29
node.js读取文件到字符串的方法
本文实例讲述了node.js读取文件到字符串的方法。分享给大家供大家参考。具体分析如下: Node.js是一套用来编写高性能网络服务器的JavaScript工具包,一系列的变化由此开始。比较独特的是,Node.js会假设你是在POSIX环境...
2017-03-27
JS中处理时间之setUTCMinutes()方法的使用
javascript Date.setUTCMinutes()方法按照通用时间设置分钟为一个指定日期。 语法 Date.setUTCMinutes(minutesValue[, secondsValue[, msValue]]) 注:括号...
2017-03-24
vue-awesome-swiper的使用以及API整理
一、先说一个看关于vue-awesome-swiper的一个坑 vue项目的package.json中显示的&lt;span style=“color: orange;”&gt;“vue-awesome-swiper”: “^2.5.4”&...
2018-04-26
简介JavaScript中toTimeString()方法的使用
该方法返回一个Date对象在人类可读的形式时间部分。 语法 下面是参数的详细信息: 返回值: 返回Date对象的人类可读形式的时间部分。 例子: &lt;html&gt; &lt;head&gt; &lt;title&gt;JavaScri...
2017-03-24
回到顶部