ES6和ES5的区别和扩展1--

ES6介绍:https://es6.ruanyifeng.com/#docs/intro

博客参考:https://www.cnblogs.com/sgs123/p/11481396.html

一 let和const

ES6 新增了let命令,用来声明变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效。

let与var的区别

  • let不存在变量提升
  • 块级作用域:ES5 只有全局作用域和函数作用域,没有块级作用域(ES6 的块级作用域必须有大括号,如果没有大括号,JavaScript 引擎就认为不存在块级作用域)
  • let不允许在相同作用域内,重复声明同一个变量

const常量

  • const与let一样,唯一区别在于声明的常量不能被修改

函数声明

  • ES5 规定,函数只能在顶层作用域和函数作用域之中声明,不能在块级作用域声明
  • ES6 引入了块级作用域,明确允许在块级作用域之中声明函数。函数声明语句的行为类似于let,在块级作用域之外不可引用。

二 变量的解构赋值

1 数组解构

es6支持“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值,如果解构不成功,变量的值就等于undefined

let [a, b, c] = [1, 2, 3] // a=1, b=2, c=3

let [a1, b1=2] = [1] // a1=1, b1=2 //指定默认值

let [d, [e], f] = [1, [2], 3] // 嵌套数组解构 d=1, e=2, f=3

let [g, ...h] = [1, 2, 3] // 数组拆分 g=1, h=[2, 3]

let [i,,j] = [1, 2, 3] // 不连续解构 i=1, j=3

let [k,l] = [1, 2, 3] // 不完全解构 k=1, l=2

事实上,只要某种数据结构具有 Iterator 接口,都可以采用数组形式的解构赋值

2 对象解构

对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值

let {a, b} = {a:'aa', b:'bb'} //a='aa' b='bb'

//设置默认值
let {x, y = 5} = {x: 1}; //x= 1 y=5

//允许别名,a的值将失效
let {a:a1,b} = {a:'aa', b:'bb'} //a1='aa' b='bb' 

let obj = {a:'aa', b: {c:'c'}}
let {a, b:{c}} = obj // 嵌套解构 a='aa' c='c'

(1)如果要将一个已经声明的变量用于解构赋值,必须非常小心

//将一个已经声明的变量用于解构赋值
let x;
({x} = {x: 1});//将一个已经声明的变量用于解构赋值 x=1
{x} = {x: 1};// SyntaxError: syntax error

(2)解构赋值允许等号左边的模式之中,不放置任何变量名

({} = [true, false]);
({} = 'abc');
({} = []);

(3)由于数组本质是特殊的对象,因此可以对数组进行对象属性的解构

let arr = [1, 2, 3];
let {0 : first, [arr.length - 1] : last} = arr;//first:1 last: 3

3 字符串的解构赋值

let [a, b, c] = 'hello' // a='h' b='e' c='l'
let {length : len} = 'hello'; //len: 5

4 数值和布尔值的解构赋值 

解构赋值的规则是,只要等号右边的值不是对象或数组,就先将其转为对象

undefinednull无法转为对象,所以对它们进行解构赋值,都会报错

let {toString: s} = 123;
s === Number.prototype.toString // true
let {toString: s} = true;
s === Boolean.prototype.toString // true


let { prop: x } = undefined; // TypeError
let { prop: y } = null; // TypeError

5 函数参数的解构赋值 

function say({name,age}){
    console.log(name + '今年' + age)
} 
say({name:'小明',age:18})

函数参数的解构也可以使用默认值。

function move({x = 0, y = 0} = {}) {
  return [x, y];
}

move({x: 3, y: 8}); // [3, 8]
move({x: 3}); // [3, 0]
move({}); // [0, 0]
move(); // [0, 0]

function move({x, y} = { x: 0, y: 0 }) {
  return [x, y];
}

move({x: 3, y: 8}); // [3, 8]
move({x: 3}); // [3, undefined]
move({}); // [undefined, undefined]
move(); // [0, 0]
  • 扩展方法

三、字符串的扩展

1 加强了对 Unicode 的支持

加强了对 Unicode 的支持,允许采用\uxxxx形式表示一个字符,其中xxxx表示字符的 Unicode 码点。(\u0000~\uFFFF之间)

ES6 对这一点做出了改进,只要将码点放入大括号,就能正确解读该字符

'\z' === 'z'  // true
'\172' === 'z' // true
'\x7A' === 'z' // true
'\u007A' === 'z' // true
'\u{7A}' === 'z' // true

2 JSON.stringify() 的改造

根据标准,JSON 数据必须是 UTF-8 编码。但是,现在的JSON.stringify()方法有可能返回不符合 UTF-8 标准的字符串。

如果遇到0xD8000xDFFF之间的单个码点,或者不存在的配对形式,它会返回转义字符串,留给应用自己决定下一步的处理

JSON.stringify('\u{D834}') // ""\\uD834""
JSON.stringify('\uDF06\uD834') // ""\\udf06\\ud834""

3 模板字符串

用反引号(`)标识,字符串中嵌入变量用${}

新增方法

ES5 提供String.fromCharCode()方法,用于从 Unicode 码点返回对应字符,但是这个方法不能识别码点大于0xFFFF的字符。

ES6 提供String.fromCodePoint()方法,可以识别大于0xFFFF的字符,弥补了String.fromCharCode()方法的不足

String.fromCharCode(0x20BB7)//String.fromCharCode()不能识别大于0xFFFF的码点,所以0x20BB7就发生了溢出,最高位2被舍弃了,最后返回码点U+0BB7对应的字符

String.fromCodePoint(0x20BB7)// "𠮷"
String.fromCodePoint(0x78, 0x1f680, 0x79) === 'x\uD83D\uDE80y'// true
//如果String.fromCodePoint方法有多个参数,则它们会被合并成一个字符串返回。

fromCodePoint方法定义在String对象上,而codePointAt方法定义在字符串的实例对象上。 

该方法返回一个斜杠都被转义(即斜杠前面再加一个斜杠)的字符串,往往用于模板字符串的处理方法。如果原字符串的斜杠已经转义,那么String.raw()会进行再次转义。

String.raw`Hi\n${2+3}!`
// 实际返回 "Hi\\n5!",显示的是转义后的结果 "Hi\n5!"

String.raw`Hi\u000A!`;
// 实际返回 "Hi\\u000A!",显示的是转义后的结果 "Hi\u000A!

// `foo${1 + 2}bar`等同于
String.raw({ raw: ['foo', 'bar'] }, 1 + 2) // "foo3bar"

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

let s = '𠮷a';//“𠮷a”视为三个字符
s.codePointAt(0) // 134071
s.codePointAt(1) // 57271
s.codePointAt(2) // 97

//测试一个字符由两个字节还是由四个字节组成的最简单方法。
function is32Bit(c) {
  return c.codePointAt(0) > 0xFFFF;
}
is32Bit("𠮷") // true
is32Bit("a") // false

将字符的不同表示方法统一为同样的形式,这称为 Unicode 正规化。

'\u01D1'.normalize() === '\u004F\u030C'.normalize()// true
let str = 'hello world'
//返回布尔值,表示是否找到了参数字符串
str.includes('r')  //true 

//返回布尔值,表示参数字符串是否在原字符串的头部
str.startsWith('hello')  //true

//返回布尔值,表示参数字符串是否在原字符串的尾部
str.endsWith('d')  //true
//repeat方法返回一个新字符串,表示将原字符串重复n次。
'x'.repeat(3) // "xxx"
'na'.repeat(0) // ""

如果repeat的参数是负数或者Infinity,会报错。参数NaN等同于 0,如果repeat的参数是字符串,则会先转换成数字。

如果某个字符串不够指定长度,会在头部或尾部补全。padStart()用于头部补全,padEnd()用于尾部补全。

'x'.padStart(5, 'ab') // 'ababx'

'x'.padEnd(5, 'ab') // 'xabab'
'x'.padEnd(4, 'ab') // 'xaba'

如果省略第二个参数,默认使用空格补全长度。

对字符串实例新增了trimStart()trimEnd()这两个方法。它们的行为与trim()一致,trimStart()消除字符串头部的空格,trimEnd()消除尾部的空格。它们返回的都是新字符串,不会修改原始字符串。

let str = '   hello world      '
//消除首尾的空格
str.trim()  //'hello world'

//消除字符串头部的空格
str.trimStart()  //'hello world   '

//消除尾部的空格
str.trimEnd()  //'   hello world'

matchAll()方法返回一个正则表达式在当前字符串的所有匹配

四 正则的扩展

1 正则的扩展

ES5 中,RegExp构造函数的参数有两种情况

//两种方式
var regex = new RegExp(/xyz/i);
var regex = new RegExp('xyz', 'i');

var regex = new RegExp(/xyz/, 'i'); //error

ES6 :如果RegExp构造函数第一个参数是一个正则对象,那么可以使用第二个参数指定修饰符。而且,返回的正则表达式会忽略原有的正则表达式的修饰符,只使用新指定的修饰符。

new RegExp(/abc/ig, 'i').flags  // "i"

2 字符串的正则方法 

字符串对象共有 4 个方法,可以使用正则表达式:match()replace()search()split()

3 u 修饰符

对正则表达式添加了u修饰符,含义为“Unicode 模式”,用来正确处理大于\uFFFF的 Unicode 字符。

/^\uD83D/u.test('\uD83D\uDC2A') // false
/^\uD83D/.test('\uD83D\uDC2A') // true
//ES5 不支持四个字节的 UTF-16 编码,会将其识别为两个字符,导致第二行代码结果为tru

一旦加上u修饰符号,就会修改下面这些正则表达式的行为。

  • 对于码点大于0xFFFF的 Unicode 字符,点字符不能识别,必须加上u修饰符。
  • ES6 新增了使用大括号表示 Unicode 字符,这种表示法在正则表达式中必须加上u修饰符,才能识别当中的大括号,否则会被解读为量词
  • 使用u修饰符后,所有量词都会正确识别码点大于0xFFFF的 Unicode 字符。
  • u修饰符也影响到预定义模式,能否正确识别码点大于0xFFFF的 Unicode 字符。
  • 没有u修饰符的情况下,正则中没有定义的转义(如逗号的转义\,)无效,而在u模式会报错。
var s = '𠮷';

/^.$/.test(s) // false
/^.$/u.test(s) // true

/\u{61}/.test('a') // false
/\u{61}/u.test('a') // true

/𠮷{2}/.test('𠮷𠮷') // false
/𠮷{2}/u.test('𠮷𠮷') // true

RegExp.prototy

//unicode属性,表示是否设置了u修饰符。
const r2 = /hello/u;
r2.unicode // true

4 y修饰符

ES6 还为正则表达式添加了y修饰符,叫做“粘连”(sticky)修饰符。

y修饰符的作用与g修饰符类似,也是全局匹配,后一次匹配都从上一次匹配成功的下一个位置开始。不同之处在于,g修饰符只要剩余位置中存在匹配就可,而y修饰符确保匹配必须从剩余的第一个位置开始,这也就是“粘连”的涵义。

var s = 'aaa_aa_a';
var r1 = /a+/g;
var r2 = /a+/y;

r1.exec(s) // ["aaa"]
r2.exec(s) // ["aaa"]

r1.exec(s) // ["aa"]
r2.exec(s) // null
//由于g修饰没有位置要求,所以第二次执行会返回结果,而y修饰符要求匹配必须从头部开始,所以返回null。

RegExp.prototype.sticky 属性

表示是否设置了y修饰符。

var r = /hello\d/y;
r.sticky // true

5 RegExp.prototype.flags 属性

ES6 为正则表达式新增了flags属性,会返回正则表达式的修饰符。

// ES5 的 source 属性
/abc/ig.source // "abc"

// ES6 的 flags 属性 返回正则表达式的修饰符
/abc/ig.flags // 'gi'

6 s 修饰符:dotAll 模式

正则表达式中,点(.)是一个特殊字符,代表任意的单个字符,但是有两个例外。一个是四个字节的 UTF-16 字符,这个可以用u修饰符解决;另一个是行终止符(该字符表示一行的终结)

  • U+000A 换行符(\n
  • U+000D 回车符(\r
  • U+2028 行分隔符(line separator)
  • U+2029 段分隔符(paragraph separator)

dotAll模式,即点(dot)代表一切字符。 

re=/foo.bar/s
re.test('foo\nbar') // true
/foo.bar/.test('foo\nbar') // false

re.dotAll // true

正则表达式还引入了一个dotAll属性,返回一个布尔值,表示该正则表达式是否处在dotAll模式。

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值