资讯专栏INFORMATION COLUMN

es6学习笔记-字符串的扩展_v1.0_byKL

JaysonWang / 2624人阅读

摘要:学习笔记字符串的扩展字符的表示法允许使用的形式表示一个字符,但在之前,单个码点仅支持到,超出该范围的必须用双字节形式表示,否则会解析错误。返回布尔值,表示参数字符串是否在源字符串的头部。,是引入了字符串补全长度的功能。

es6学习笔记-字符串的扩展_v1.0 字符的Unicode表示法

JavaScript 允许使用uxxxx的形式表示一个字符,但在 ES6 之前,单个码点仅支持u0000到uFFFF,超出该范围的必须用双字节形式表示,否则会解析错误。ES6对这一点做出了改进,只要将码点放入大括号,就能正确解读该字符,不受限于4位。例如下面的写法就是合法的,能够被正确解析:

//在es6后才可以,在es5的时候不行
"u{20BB7}"  // "?"
codePointAt()

JavaScript内部,字符以UTF-16的格式储存,每个字符固定为2个字节。

对于那些需要4个字节储存的字符(Unicode码点大于0xFFFF的字符),JavaScript会认为它们是两个字符。

codePointAt方法,能够正确处理4个字节储存的字符,返回一个字符的码点。

codePointAt方法会正确返回32位的UTF-16字符的码点。

注意例子是?,汉字“?”(注意,这个字不是”吉祥“的”吉“)的码点是0x20BB7,UTF-16编码为0xD842 0xDFB7(十进制为55362 57271),需要4个字节储存。

var s = "?a";

console.log(s.length); //3,?使用了2个字节来存储,a使用了一个字节存储
console.log(s.codePointAt(0)); // 134071
console.log(s.codePointAt(1)); // 57271
console.log(s.codePointAt(2)); // 97

codePointAt方法是测试一个字符由两个字节还是由四个字节组成的最简单方法。

function is32Bit(c) {
    //超过2个字节组成的字符串的第一位码点都是大于0xFFFF
    return c.codePointAt(0) > 0xFFFF;
}

console.log(is32Bit("?")) // true
console.log(is32Bit("a")) // false

ES6 提供了 codePointAt(),能够正确处理4个字节存储的字符,返回一个字符的码点。

但需要注意的是,这并没有改变 JavaScript 将2个字节视为1个字符的事实,只是自动识别出了这是个4字节的字符并返回了正确的码点而已

对于单个4字节的字符(例如"?")来说,charPointAt(0)返回完整字符的十进制码点,charPointAt(1)返回这个字符的后2个字节的十进制码点,效果等同于charCodeAt(1)。
参考

var s = "?a";
for (let ch of s) { //遍历s字符串,会有2个字符串被遍历,因为他的长度是2
  console.log(ch.codePointAt(0));
}
// 134071,能知道这是一个超过四位(2个字节)的字符串(?)
// 97,这是一个只需要2位(1个字节)的字符串(a)

编码格式的检测:

专家给每种格式和字节序规定了一些特殊的编码,这些编码在unicode 中是没有使用的,所以不用担心会冲突。这个叫做BOM(Byte Order Mark)头。意思是字节序标志头。通过它基本能确定编码格式和字节序。
UTF编码 ║ Byte Order Mark   
UTF-8   ║ EF BB BF   
UTF-16LE ║ FF FE   
UTF-16BE ║ FE FF   
UTF-32LE ║ FF FE 00 00   
UTF-32BE ║ 00 00 FE FF
所以通过检测文件前面的BOM头,基本能确定编码格式和字节序。但是这个BOM头只是建议添加,不是强制的,所以不少软件和系统没有添加这个BOM头(所以有些软件格式中有带BOM头和NoBOM头的选择)

UTF-16长度相对固定,只要不处理大于U200000范围的字符,每个Unicode代码点使用16位即2字节表示,超出部分使用两个UTF-16即4字节表示。按照高低位字节顺序,又分为UTF-16BE/UTF-16LE。参考

String.fromCodePoint()

String.fromCodePoint()就是和codePointAt()做相反的操作了。例如:

console.log(String.fromCodePoint(134071));  // "?"
字符串的遍历器接口

这个遍历器最大的优点是可以识别大于0xFFFF的码点

for (let codePoint of "foo") {
  console.log(codePoint)
}
// "f"
// "o"
// "o"

//能识别大于0xFFFF的码点
var text = String.fromCodePoint(0x20BB7);

//用for不行
for (let i = 0; i < text.length; i++) {
  console.log(text[i]);
}
// " "
// " "

//用遍历器可以
for (let i of text) {
  console.log(i);
}
// "?"
includes(), startsWith(), endsWith()

传统上,JavaScript只有indexOf方法,可以用来确定一个字符串是否包含在另一个字符串中。ES6又提供了三种新方法。

includes():返回布尔值,表示是否找到了参数字符串。

startsWith():返回布尔值,表示参数字符串是否在源字符串的头部。

endsWith():返回布尔值,表示参数字符串是否在源字符串的尾部。

var s = "Hello world!";
//第二个参数代表开始位置
console.log(s.startsWith("world", 6))// true
console.log(s.endsWith("Hello", 5)) // true
console.log(s.includes("Hello", 6)) // false
repeat()

repeat方法返回一个新字符串,表示将原字符串重复n次。

console.log("x".repeat(3)) // "xxx"
console.log("na".repeat(0)) // ""
console.log("na".repeat(2.9)) // "nana"
"na".repeat(Infinity)// RangeError
"na".repeat(-1)// RangeError
padStart(),padEnd()

ES2017(es6是es2016) 引入了字符串补全长度的功能。如果某个字符串不够指定长度,会在头部或尾部补全。padStart()用于头部补全,padEnd()用于尾部补全。

padStart和padEnd一共接受两个参数,第一个参数用来指定字符串的最小长度,第二个参数是用来补全的字符串。

//主要用于补全
console.log("1".padStart(10, "0")); // "0000000001"
console.log("12".padStart(10, "0"))// "0000000012"
console.log("123456".padStart(10, "0")) // "0000123456"

node 6.95还不支持,现在是用babel-node来测试的

模板字符串

使用反引号,反引号代替以前的单引号或者双引号

使用大括号支持任意的JavaScript表达式,可以进行运算,以及引用对象属性和函数

// 普通字符串
`In JavaScript "
" is a line-feed.`

// 多行字符串
`In JavaScript this is
 not legal.`

console.log(`string text line 1
string text line 2`);

// 字符串中嵌入变量
var name = "Bob", time = "today";
`Hello ${name}, how are you ${time}?`   

//如果在模板字符串中需要使用反引号,则前面要用反斜杠转义。
var greeting = ``Yo` World!`;


//使用大括号的情况
var x = 1;
var y = 2;

`${x} + ${y} = ${x + y}`
// "1 + 2 = 3"

`${x} + ${y * 2} = ${x + y * 2}`
// "1 + 4 = 5"

var obj = {x: 1, y: 2};
`${obj.x + obj.y}`
// 3

//模板字符串之中还能调用函数,要用大括号
function fn() {
  return "Hello World";
}

`foo ${fn()} bar`
// foo Hello World bar

传统写法vs新写法

//传统写法
$("#result").append(
  "There are " + basket.count + " " + //不断用+号连接
  "items in your basket, " +
  "" + basket.onSale +
  " are on sale!"
);
//新写法
$("#result").append(` //一个反引号括起来,然后直接写,用大括号包括变量
  There are ${basket.count} items
   in your basket, ${basket.onSale}
  are on sale!
`);

//模板字符串中嵌入变量,需要将变量名写在${}之中。
function authorize(user, action) {
  if (!user.hasPrivilege(action)) {
    throw new Error(
      // 传统写法为
      // "User "
      // + user.name
      // + " is not authorized to do "
      // + action
      // + "."
      
      //新写法
      `User ${user.name} is not authorized to do ${action}.`);
  }
}

模板嵌套

map() 方法创建一个新数组,其结果是该数组中的每个元素调用一个提供的函数。

const tmpl = addrs => ` //箭头后面跟的是反引号
  
  ${addrs.map(addr => ` //不断解析,直到获取到data数组的元素里面的对象属性
    
  `).join("")}//将他们直接连接起来
  
${addr.first}
${addr.last}
`; //初始化需要处理的模板 const data = [ { first: "", last: "Bond" }, { first: "Lars", last: "" }, ]; console.log(tmpl(data)); //返回结果 // // // // // // // // //
Bond
Lars

如果需要引用模板字符串本身,在需要时执行,可以像下面这样写。

// 写法一
let str = "return " + "`Hello ${name}!`";//将模板本身保存起来为变量
let func = new Function("name", str); //作为functionBody使用
func("Jack") // "Hello Jack!"

// 写法二
let str = "(name) => `Hello ${name}!`"; 
let func = eval.call(null, str); //不建议使用eval
func("Jack") // "Hello Jack!"

new Function ([arg1[, arg2[, ...argN]],] functionBody)

参数arg1, arg2, ... argN:被函数使用的参数的名称必须是合法命名的。

functionBody:一个含有包括函数定义的JavaScript语句的字符串。

参考引用:

es6字符串扩展

每天一点ES6(5):字符串的扩展

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/86911.html

相关文章

  • es6学习笔记-数值扩展_V1.0_byKL

    摘要:学习笔记数值的扩展有一些不常用或者还不支持的就没有记录了总体来说本篇只是一个备忘而已用来检查一个数值是否为有限的。两个新方法只对数值有效,非数值一律返回。参考引用数值扩展 es6学习笔记-数值的扩展 有一些不常用或者还不支持的就没有记录了,总体来说本篇只是一个备忘而已 Number.isFinite(), Number.isNaN() Number.isFinite()用来检查一个数值...

    宋华 评论0 收藏0
  • es6学习笔记-函数扩展_v1.0_byKL

    摘要:学习笔记函数扩展函数参数的默认值如果参数默认值是变量,那么参数就不是传值的,而是每次都重新计算默认值表达式的值。属性函数的属性,返回该函数的函数名。箭头函数详细链接参考引用函数扩展 es6学习笔记-函数扩展_v1.0 函数参数的默认值 function Point(x = 0, y = 0) { this.x = x; this.y = y; } var p = ne...

    yuanzhanghu 评论0 收藏0
  • es6学习笔记-let,const和块级作用域_v1.0_byKL

    摘要:考虑到环境导致的行为差异太大,应该避免在块级作用域内声明函数。函数声明语句函数表达式循环循环还有一个特别之处,就是循环语句部分是一个父作用域,而循环体内部是一个单独的子作用域。声明一个只读的常量。 es6学习笔记-let,const和块级作用域_v1.0 块级作用域 javascript 原来是没有块级作用域的,只有全局作用域和函数作用域 例子1 因为没有块级作用域,所以每次的i都是一...

    Youngdze 评论0 收藏0
  • es6学习笔记-符串模板_v1.0_byKL

    摘要:学习笔记字符串模板实例模板编译先组成一个模板使用放置代码使用输出表达式。这被称为标签模板功能。该数组的成员与数组完全一致参考引用字符串扩展 es6学习笔记-字符串模板_v1.0 实例:模板编译 //先组成一个模板 var template = ` //使用放置JavaScript代码 //使用输出JavaScript表达式。 `; //这是编译模板的函数,将模...

    xiongzenghui 评论0 收藏0
  • es6学习笔记-顶层对象_v1.0_byKL

    摘要:学习笔记顶层对象虽然是笔记但是基本是抄了一次大师的文章了顶层对象顶层对象,在浏览器环境指的是对象,在指的是对象。之中,顶层对象的属性与全局变量是等价的。的写法模块的写法上面代码将顶层对象放入变量。参考引用顶层对象实战 es6学习笔记-顶层对象_v1.0 (虽然是笔记,但是基本是抄了一次ruan大师的文章了) 顶层对象 顶层对象,在浏览器环境指的是window对象,在Node指的是gl...

    Meils 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<