七月学习之E6、ES7、ES8、ES9、ES10、ES11新特性
目录
- ES6新特性(2015)
- 1. let 和 const 命令
- 2. 解构赋值
- 3. 扩展运算符(spread)
- 4. 箭头函数
- 5. 函数参数默认值
- 6. 模板字符串
- 7. 对象属性和方法的简写
- 8. 类(class)
- 9. 模块化(module)
- 10. Promise 对象
- 12. Set 和 Map 数据结构
- 13. Iterator 遍历器/迭代器
- 14. Symbol
- ES7新特性(2016)
- 1. Array.prototype.includes()
- 2. 指数操作符 `**`
- ES8新特性(2017)
- 1. async函数
- 2. Object.values()
- 3. Object.entries()
- 4. String.prototype.padStart 和 String.prototype.padEnd
- 5. 函数参数列表结尾允许逗号
- 6. Object.getOwnPropertyDescriptors()
- 7. SharedArrayBuffer对象
- 8. Atomics对象
- ES9新特性(2018)
- 1. Rest(剩余)/Spread(展开) 属性
- 2. Asynchronous iteration (异步迭代)
- 3. Promise.prototype.finally()
- 4. 正则表达式之后行断言(lookbehind)
- 5. 正则表达式之命名捕获组
- 6. 正则表达式之dotAll模式
- 7. 正则表达式之Unicode 属性转义 \p{…} 和 \P{…}
- ES10新特性(2019)
- 1. 可选的 catch 绑定
- 2. JSON Superset 超集
- 3. Symbol.prototype.description
- 4. Function.prototype.toString
- 5. Object.fromEntries
- 6. JSON.stringify() 加强格式转化
- 7. String.prototype.trimStart() / String.prototype.trimEnd()
- 8. Array.prototype.flat() / Array.prototype.flatMap()
- ES11新特性(2020)
- 1. 空值合并运算符 `??`
- 2. 可选链运算符`?.`
- 3. 使用 `#` 号快速创建类的私有变量
- 4. Promise.allSelected
- 5. BigInt
- 6. 使用 async/await 动态导入模块
ES6新特性(2015)
1. let 和 const 命令
let
命令用于声明变量,const
命令用来声明常量。
相比于 ES5 的 var
命令而言,let
和 const
有以下不同点:
不存在变量声明提升
我们都知道,var
存在变量声明提升,如下:console.log(num); //undefined console.log(num2); //ReferenceError console.log(num3); //ReferenceErrorvar num = 1; let num2 = 2; const num3 = 3;
代码中所谓的变量声明提升是指
var num
变量声明语句提升,而num = 1
赋值不会提升,所以打印结果为undefined
。
而let
不存在变量声明提升,所以let num2
不会提升,所以打印报错。
const
用于声明常量,也不存在声明提升,所以打印也报错。块级作用域
ES5 只有全局作用域和函数作用域,没有块级作用域。
一般而言,使用大括号{}
包裹的这部分代码,就是一个块级作用域。{let num = 0; //块级作用域 }
而
let
和const
只在声明它的块级作用域有效,在其他块级作用域无法访问。暂时性死区
了解了什么是块级作用域后,那么我们知道,let
声明的变量和const
声明的常量只在自己的块级作用域生效。
但是是不是在本作用域任何位置都可以访问到它们定义的变量或常量呢?
答案是否定的~
看下面这段代码:{num = 0;console.log(num) //ReferenceErrorlet num; }
打印会报错,因为
let
声明的变量不提升。而在这个变量声明之前,这个变量都是不可用的
,这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)
。不允许重复声明
let
和const
不允许在相同作用域内,重复声明同一个变量或常量。{let num = 0;let num = 1;console.log(num); //SyntaxError: Identifier 'num' has already been declared } {const num = 0;const num = 1;console.log(num); //SyntaxError: Identifier 'num' has already been declared }
如上代码,使用
let
或者const
重复声明会报错。使用 const 赋值后的值不可修改
const
声明定义的是一个常量,常量通常都是不可变的。let num2 = 2; num2 = 3; console.log(num2); //3const num = 0; num = 1; console.log(num); //TypeError: Assignment to constant variable.
如上代码,使用
const
修改一个值会报错,而let
和var
可以随意修改。
2. 解构赋值
ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。
- 数组的结构赋值
E5 中,要给变量赋值是直接使用如下:var foo = 0;
现在可以使用数组对变量进行赋值:
var [a, b] = [1, 2]; console.log(a, b); // 1 2
除了可以进行赋值外,也方便变量的赋值转换。什么意思呢?就是改变两个变量的值。
//ES5 var a = 1; var b = 2; //如何让变量 a b值交换呢? 声明一个中间变量 var c = a; a = b; b = c; console.log(a, b); // 2 1 //上述方法太过麻烦,使用数组的结构赋值一步到位 var [a , b] = [2, 1] console.log(a, b); // 2 1
如果解构不成功,变量的值就等于
undefined
。let [foo] = []; //foo:undefined let [bar, foo] = [1]; //foo:undefined
还有一个使用扩展运算符赋值结构的,在第三点扩展运算符详细讲解。
- 对象的结构赋值
let obj = {person:{name: 'zs',age: 18} } let { person } = obj; console.log(person); //{ name: 'zs', age: 18 }
3. 扩展运算符(spread)
数组的扩展运算符
let [head, ...tail] = [1, 2, 3, 4]; head // 1 tail // [2, 3, 4]
函数参数的扩展运算符
function foo(...tail){console.log(tail); }console.log(foo(1,2,3)); //[ 1, 2, 3 ]
4. 箭头函数
- 箭头函数与普通函数的四大区别:
- 箭头函数中的
this
指向其父作用域中的this
- 箭头函数不能使用argumnts对象,使用
...
扩展运算符代替 - 箭头函数不能用作构造函数
- 箭头函数不可以使用
yeild
表达式,因此不可用用作Generator函数
- 箭头函数中的
这里主要介绍一下第二点
和第四点
。
- 函数的
arguments
对象
普通函数内部,拥有类数组对象arguments
,用来存储传入函数的参数。其中length
属性代表传入函数中参数的个数,callee
指向拥有这个arguments
的函数。function foo(){console.log(arguments); //[Arguments] { '0': 1, '1': 2, '2': 3 }console.log(arguments.length); //3console.log(arguments.callee); //[Function: foo] }console.log(foo(1,2,3));
特别的,箭头函数中没有
arguments
,若是可以打印出来,那也是属于父作用域的 - Generator函数
Generator 函数是 ES6 提供的一种异步编程解决方案,可以暂缓执行,分段使用。
形式上,Generator 函数是一个普通函数,但是有两个特征。一是,function关键字与函数名之间有一个星号;二是,函数体内部使用yield表达式,定义不同的内部状态。function* foo(){yield 1;yield 2;return 3; } let fun = foo(); console.log(fun.next()) //{ value: 1, done: false } console.log(fun.next()) //{ value: 2, done: false } console.log(fun.next()) //{ value: 3, done: true } console.log(fun.next()) //{ value: undefined, done: true }
第一次调用
next
方法,在碰到的第一个yield
停止,next
方法返回一个对象,它的value
属性就是当前yield表达式的值1,done属性的值false,表示遍历还没有结束。
第二次如第一次。
第三次调用,Generator 函数从上次yield
表达式停下的地方,一直执行到return
语句(如果没有return
语句,就执行到函数结束)。next
方法返回的对象的value
属性,就是紧跟在return
语句后面的表达式的值(如果没有return
语句,则value
属性的值为undefined),done
属性的值true,表示遍历已经结束。
第四次调用,此时 Generator 函数已经运行完毕,next
方法返回对象的value
属性为undefined,done
属性为true。以后再调用next
方法,返回的都是这个值。
5. 函数参数默认值
ES6支持在定义函数的时候为其设置默认值:
function foo(a, b, c=3, d){return {a,b,c,d}
}
console.log(foo(1,2,0,4));
console.log(foo.length); //2
函数的 length
属性,将返回没有指定默认值的参数个数,遇到有默认值的参数就会停止。
6. 模板字符串
使用反引号将变量放在${}
中。
- 不使用模板字符串
var name = 'Your name is ' + first + ' ' + last + '.'
- 使用模板字符串
var name = `Your name is ${first} ${last}.`
7. 对象属性和方法的简写
- 不使用ES6
let name = 'tom', age = 18; let obj = {name:name,age:age,fun:function(){console.log('hello');} } console.log(obj); //{ name: 'tom', age: 18, fun: [Function: fun] }
- 使用ES6
let name = 'tom', age = 18; let obj = {name,age,fun(){console.log('hello');} } console.log(obj); //{ name: 'tom', age: 18, fun: [Function: fun] }
8. 类(class)
JavaScript中的构造函数跟传统的面向对象语言(比如 C++ 和 Java)差异很大,很容易让新学习这门语言的程序员感到困惑。
ES6 提供了更接近传统语言的写法,引入了 class(类)
这个概念,作为对象的模板。通过class
关键字,可以定义类。
基本上,ES6 的class
可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的class
写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。
class Animal{constructor(name,color){this.name = name;this.color = color;}sayHi(){console.log('HI~');}static sayStatic(){console.log('static');}
}
Animal.age = 18;class Dog extends Animal{constructor(name,color,gender){super(name,color);this.gender = gender;}
}
let dog = new Dog('hh','black','female');
console.log(dog);
console.log(dog.sayHi());
console.log(Dog.sayStatic());
console.log(Dog.age);
// 静态属性方法的继承,表示构造函数的继承,子类的__proto__属性,总是指向父类
console.log(Dog.__proto__ === Animal);
// 实例属性方法的继承,子类prototype属性的__proto__属性,总是指向父类的prototype属性
console.log(Dog.prototype.__proto__===Animal.prototype);
// prototype代表构造函数的原型对象,子类构造函数的原型对象有一个指针及__proto__,总是指向父类构造函数的原型对象
// X.prototype表示的是X类的实例,X表示X类及构造函数X
注意:
constructor
方法,这就是构造方法,而this
关键字则代表实例对象。- 类的静态方法使用
static
关键字定义,静态属性在类的外部自行定义,子类可以继承父类的静态方法和静态方法。 super
虽然代表了父类的构造函数,但是返回的是子类的实例,即super
内部的this
指的是的子类实例,相当于调用的父类的constructor
方法。- 子类必须在
constructor
方法中调用super
方法,否则新建实例时会报错。这是因为子类自己的this
对象,必须先通过父类的构造函数完成塑造,得到与父类同样的实例属性和方法,然后再对其进行加工,加上子类自己的实例属性和方法。如果不调用super
方法,子类就得不到this
对象。
9. 模块化(module)
历史上,JavaScript 一直没有模块(module
)体系,无法将一个大程序拆分成互相依赖的小文件,再用简单的方法拼装起来。其他语言都有这项功能,比如 Ruby 的require
、Python 的import
,甚至就连 CSS 都有@import
,但是 JavaScript 任何这方面的支持都没有,这对开发大型的、复杂的项目形成了巨大障碍。
在 ES6 之前,社区制定了一些模块加载方案,最主要的有 CommonJS
和 AMD
两种。前者用于服务器,后者用于浏览器。ES6 在语言标准的层面上,实现了模块功能,而且实现得相当简单,完全可以取代 CommonJS
和 AMD
规范,成为浏览器和服务器通用的模块解决方案。
ES6 模块的设计思想是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。
export
命令
用于规范模块的对外接口。
导出内容供其他模块使用,一个模块中,export
可以调用多次。
export
必须与模块内部变量建立一对一的关系,所以不能直接导出一个值。可以使用export default
默认导出一个值。export let a = 1;let b = 2; export {b};let c = 3; export {c as d} //更改变量名
export default
命令
用于指定模块的默认导出。
一个模块只能有一个默认导出。//1. 导出一个匿名函数 export default function(){} //2. 导出一个字符串 export default 'test' //3. 导出一个变量 let a = 1; export default a; //4. 导出一个对象 let obj = {}; export default obj
import
命令//1. 解构导入 import {a, b, test} from './module'; //2. 重命名变量 import {a as b} from './module'; //3. 模块的整体加载 import * as obj from './module'; //4. 默认模块的导入 import test from './module';
10. Promise 对象
Promise 是异步编程的一种解决方案,比传统的解决方案callback更加的优雅。它最早由社区提出和实现的,ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象。
- 是一个容器,存放着某个未来才会结束的事件结果(通常是一个异步操作)
- 是一个对象,可以获取到异步操作的消息。
参数是一个异步处理函数,如果异步执行成功,调用resolve
函数,如果异步执行失败,调用reject
函数
let p = new Promise((resolve,reject)=>{//异步操作});
内部异步执行成功的回调函数 p.then((response)=>{});
内部异步执行失败的回调函数 p.catch((error)=>{});
Promise.prototype.catch
方法是.then(null, rejection)
的别名,用于指定发生错误时的回调函数。
有了Promise对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。
嵌套两个setTimeout回调函数:
//不使用ES6
setTimeout(function()
{console.log('ONE'); // 1秒后输出"ONE"setTimeout(function(){console.log('TWO'); // 2秒后输出"TWO"}, 1000);
}, 1000);//使用ES6
let p = new Promise((resolve,reject)=>{setTimeout(resolve,1000)
})
let p2 = new Promise((resolve,reject)=>{setTimeout(resolve,2000)
})
p.then(()=>{console.log('ONE');return p2
})
.then(()=>{console.log('TWO');
})
12. Set 和 Map 数据结构
- Set 数据结构
类似于数组,但成员的值是唯一的,没有重复的值
去除数组中的重复成员[...new Set(arr)]
- Set原型对象的属性
constructor 返回当前实例的构造函数,默认就是Set
size 返回Set实例的成员总数 - Set原型对象的方法
add(value) 添加某个值,返回Set结构本身
delete(value) 删除某个值,返回一个布尔值,表示删除是否成功
has(value) 判断该值是否是Set成员,返回一个布尔值
clear() 清除所有成员,没有返回值
keys() 返回键名的Iterator遍历器对象
values() 返回键值的Iterator遍历器对象
entries() 返回键值对的Iterator遍历器对象
forEach() 使用回调函数遍历每一个成员
- Set原型对象的属性
- Map 数据结构
类似于对象,是键值对的集合,但是键的范围包括字符串及其他各种类型的数据(包括对象) 也可接受一个二维数组作为参数,该数组的成员是一个表示键值对的数组- Map原型对象的属性:
constructor 构造函数,默认为Map
size 返回Map结构的成员总数 - Map原型对象的方法:
set(key,value) 设置键名及键值,返回整个Map结构。如果键名key存在,键值会被更新,否则就新生成该键
get(key) 读取对于的键值,如果找不到,返回undefined
has(key) 判断该键是否是Map对象成员,返回一个布尔值
delete(key) 删除某个键,返回一个布尔值
clear() 清除所有成员,没有返回值
keys() 返回键名的Iterator迭代器对象
values() 返回键值的Iterator迭代器对象
entries() 返回键值对的Iterator迭代器对象
forEach() 使用回调函数遍历每一个成员
- Map原型对象的属性:
13. Iterator 遍历器/迭代器
是一种接口,为各种不同的数据结构提供统一的访问机制,即for-of循环。 任何数据结构,只要部署了Iterator接口,就可以完成遍历操作。 一种数据结构只要部署了 Iterator 接口,我们就称这种数据结构是可遍历的(iterable)。
- 作用:
- 为各种数据结构,提供一个统一的,简便的访问接口。
- 使得数据结构的成员能够按照某种次序排列。
- Iterator主要供ES6新提出的遍历命令for-of循环使用
next()
方法
第一次调用Iterator的next()方法,可以将指针指向数据结构的第一个成员。
第二次调用next()方法,指针就指向数据结构的第二个成员。
不断调用Iterator的next()方法,直到它指向数据结构的结束位置。
console.log(values.next());//{ value: 1, done: false }
console.log(values.next());//{ value: 'hello', done: false }
console.log(values.next());//{ value: undefined, done: true }
可以使用for-of循环来遍历Iterator对象,或者在while语句中使用done属性来遍历。
原生JS具备Iterator接口的数据结构如下:
4. Set
5. Map
6. Array
7. String
8. 函数的arguments对象
9. NodeList对象
注意:for-of
不能用来遍历对象
14. Symbol
ES5 的对象属性名都是字符串,这容易造成属性名的冲突。比如,你使用了一个他人提供的对象,但又想为这个对象添加新的方法(mixin 模式),新方法的名字就有可能与现有方法产生冲突。如果有一种机制,保证每个属性的名字都是独一无二的就好了,这样就从根本上防止属性名的冲突。这就是 ES6 引入Symbol
的原因。
ES6 引入了一种新的原始数据类型Symbol
,表示独一无二的值。它是 JavaScript 语言的第七种数据类型,前六种是:undefined
、null
、布尔值(Boolean)、字符串(String)、数值(Number)、对象(Object)。
Symbol
值通过Symbol
函数生成。
凡是属性名属于 Symbol
类型,就都是独一无二的,可以保证不会与其他属性名产生冲突。
// 没有参数的情况
let s1 = Symbol();
let s2 = Symbol();s1 === s2 // false// 有参数的情况
let s1 = Symbol('foo');
let s2 = Symbol('foo');s1 === s2 // false
console.log(typeof s1); //symbol
ES7新特性(2016)
1. Array.prototype.includes()
includes()
函数用来判断一个数组是否包含一个指定的值,如果包含则返回 true
,否则返回false
。
let arr = [1,2,3,4]
console.log(arr.includes(1)); //true
console.log(arr.includes(5)); //false
2. 指数操作符 **
在ES7中引入了指数运算符**
,**
具有与Math.pow(..)
等效的计算结果。
console.log(Math.pow(2,3)); //8
console.log(2**3); //8
ES8新特性(2017)
1. async函数
ES2017 标准引入了 async
函数,使得异步操作变得更加方便。
async
函数是什么?一句话,它就是 Generator 函数的语法糖。
async
函数对 Generator 函数的改进,体现在以下四点:
- 内置执行器
async
函数的执行,与普通函数一模一样,只要一行。
这完全不像 Generator 函数,需要调用next方法。 - 更好的语义
async
和await
,比起星号
和yield
,语义更清楚了。async
表示函数里有异步操作,await
表示紧跟在后面的表达式需要等待结果。 - 更广的适用性
async
函数的await
命令后面,可以是 Promise 对象和原始类型的值(数值、字符串和布尔值,但这时会自动转成立即 resolved 的 Promise 对象)。 - 返回值是 Promise
async
函数的返回值是 Promise 对象,这比 Generator 函数的返回值是 Iterator 对象方便多了。你可以用then方法指定下一步的操作。
进一步说,async
函数完全可以看作多个异步操作,包装成的一个 Promise 对象,而await
命令就是内部then命令的语法糖。
//Generator函数
let gen = function*(){yield 1;yield 2;
}
let g = gen();
console.log(g.next());//{ value: 1, done: false }
console.log(g.next());//{ value: 2, done: false }
console.log(g.next());//{ value: undefined, done: true }//async函数
let gen2 = async function(){let g1 = await 1;let g2 = await 2;console.log(g1);console.log(g2);return {g1,g2}
}
gen2() // 1 2
//then()方法内返回的是async函数返回的结果
gen2().then((res)=>{console.log(res); //{g1:1,g2:2}
})
2. Object.values()
Object.values()
是一个与Object.keys()
类似的新函数,但返回的是Object自身属性的所有值,不包括继承的值。
ES5中只有 Object.keys() 方法。
let obj = {name: 'zs',age: 18
}
console.log(Object.keys(obj)); //[ 'name', 'age' ]
console.log(Object.values(obj)); //[ 'zs', 18 ]//不使用 Object.values(obj)
function getValues(obj){return Object.keys(obj).map((item)=>{return obj[item]})
}
console.log(getValues(obj)); //[ 'zs', 18 ]
3. Object.entries()
Object.entries()
函数返回一个对象自身可枚举属性的键值对的数组。
let obj = {name: 'zs',age: 18
}
console.log(Object.entries(obj)); //[ [ 'name', 'zs' ], [ 'age', 18 ] ]
for(let [key,value] of Object.entries(obj)){console.log(`key: ${key}, value: ${value}`); //key: name, value: zs//key: age, value: 18
}
4. String.prototype.padStart 和 String.prototype.padEnd
在ES8中String新增了两个实例函数String.prototype.padStart
和String.prototype.padEnd
,允许将空字符串或其他字符串添加到原始字符串的开头或结尾。
String.padStart(targetLength,[padString])
- targetLength:当前字符串需要填充到的目标长度。如果这个数值小于当前字符串的长度,则返回当前字符串本身。
- padString:(可选)填充字符串。此参数的缺省值为
" "
空字符串。
String.padEnd(targetLength,padString])
- targetLength:当前字符串需要填充到的目标长度。如果这个数值小于当前字符串的长度,则返回当前字符串本身。
- padString:(可选) 填充字符串。此参数的缺省值为
" "
空字符串。
console.log('100'.padEnd(6,'.00')); // 100.00
console.log('100'.padStart(4,'e')); // e100
5. 函数参数列表结尾允许逗号
主要作用是方便使用git进行多人协作开发时修改同一个函数减少不必要的行变更。
function foo(a,b,){console.log(a,b);
}
foo(1,2)
6. Object.getOwnPropertyDescriptors()
Object.getOwnPropertyDescriptors()
函数用来获取一个对象的所有自身属性的描述符,如果没有任何自身属性,则返回空对象。
Object.getOwnPropertyDescriptors(obj, ‘属性名’)
let obj = {name: 'zs',getName(){console.log(this.name);}
}
console.log(Object.getOwnPropertyDescriptor(obj,'name'));
// { value: 'zs', writable: true, enumerable: true, configurable: true }
- value
属性值 - writable
是否可以修改值 - enumerable
是否可枚举 - configurable
能否通过delete删除属性从而重新定义属性
7. SharedArrayBuffer对象
SharedArrayBuffer 对象用来表示一个通用的,固定长度的原始二进制数据缓冲区,类似于 ArrayBuffer 对象,它们都可以用来在共享内存(shared memory)上创建视图。与 ArrayBuffer 不同的是,SharedArrayBuffer
不能被分离。
// create a SharedArrayBuffer with a size in bytes
const buffer = new SharedArrayBuffer(8);console.log(buffer.byteLength);
// expected output: 8
8. Atomics对象
Atomics 对象提供了一组静态方法用来对 SharedArrayBuffer 对象进行原子操作。
这些原子操作属于 Atomics 模块。与一般的全局对象不同,Atomics 不是构造函数,因此不能使用 new 操作符调用,也不能将其当作函数直接调用。Atomics 的所有属性和方法都是静态的(与 Math 对象一样)。
ES9新特性(2018)
1. Rest(剩余)/Spread(展开) 属性
- 对象的扩展运算符
let obj = {name: 'zs',age: 18 } let obj2 = {...obj,gender: 'male',name: 'tom' } console.log(obj2); //{ name: 'tom', age: 18, gender: 'male' }
2. Asynchronous iteration (异步迭代)
在async/await
的某些时刻,你可能尝试在同步循环中调用异步函数。例如:
async function process(array) {for (let i of array) {await doSomething(i);}
}
这段代码中,循环本身保持同步,并在在内部异步函数之前全部调用完成。
新的 for-await-of 构造允许你使用异步可迭代对象作为循环迭代:
async function process(array) {for await (let i of array) {doSomething(i);}
}
3. Promise.prototype.finally()
finally()
允许您运行一些代码,无论 promise 的执行成功或失败:
new Promise((resolve,reject)=>{}).then(data => data.json()).catch(error => console.error(error)).finally(() => console.log('finished'))
4. 正则表达式之后行断言(lookbehind)
正则表达式后行断言(lookbehind)
:?<=
代表字符串中的一个位置,紧接该位置之前的字符序列能够匹配。/(?<=Roger) Waters//(?<=Roger) Waters/.test('Pink Waters is my dog') //false /(?<=Roger) Waters/.test('Roger is my dog and Roger Waters is a famous musician') //true
正则表达式后行断言逆操作
:?<!
代表字符串中的一个位置,紧接该位置之前的字符序列不能够匹配。/(?<!Roger) Waters//(?<!Roger) Waters/.test('Pink Waters is my dog') //true /(?<!Roger) Waters/.test('Roger is my dog and Roger Waters is a famous musician') //false
正则表达式的先行断言?=
:匹配一个字符串,该字符串后面跟着一个特定的子字符串。/Roger(?=Waters)//Roger(?= Waters)/.test('Roger is my dog') //false /Roger(?= Waters)/.test('Roger is my dog and Roger Waters is a famous musician')
正则表达式的先行断言逆操作?!
:匹配一个字符串,该字符串后面没有一个特定的子字符串。/Roger(?!Waters)//Roger(?! Waters)/.test('Roger is my dog') //true /Roger(?! Waters)/.test('Roger Waters is a famous musician') //false
5. 正则表达式之命名捕获组
ES2018允许命名捕获组使用符号?<name>
const re = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/
const result = re.exec('2015-01-02')// result.groups.year === '2015';
// result.groups.month === '01';
// result.groups.day === '02';
6. 正则表达式之dotAll模式
正则表达式中点.
匹配除回车外的任何单字符,标记s改变这种行为,允许行终止符的出现,例如:
/hello.world/.test('hello\nworld'); // false
/hello.world/s.test('hello\nworld'); // true
7. 正则表达式之Unicode 属性转义 \p{…} 和 \P{…}
ES2018添加了 Unicode 属性转义——形式为\p{...}
和\P{...}
,在正则表达式中使用标记 u
(unicode) 设置。
\p{}
匹配所有 Unicode 字符,否定为 \P{}
。
任何 unicode 字符都有一组属性。 例如,Script
确定语言系列,ASCII
是一个布尔值, 对于 ASCII
字符,值为 true,依此类推。 您可以将此属性放在花括号中,正则表达式将检查是否为真:
/^\p{ASCII}+$/u.test('abc') //true
/^\p{ASCII}+$/u.test('ABC@') //true
/^\p{ASCII}+$/u.test('ABC
七月学习之E6、ES7、ES8、ES9、ES10、ES11新特性相关推荐
- ES7 ES8 ES9 ES10 新特性总结思考
学习在于总结,发现并没有对于新出的一些语言特性进行总结,正好最近有时间,可以把这些进行总结以及运用,也许在项目中已经使用. ES7 Array includes方法 求幂运算符 ES8 Async F ...
- ES6/ES7/ES8/ES9/ES10常用特性和新特性最全总结
ES6 ES6在ES5的基础上新增了一系列特性,这里仅列出常用特性 变量的改变,添加了块级作用域的概念 let声明变量(块级作用域),let是更完美的var,它声明的全局变量不是全局属性widow的变 ...
- ES7、ES8、ES9、ES10、ES11 新特性 总结
目录 ES7新特性 一.Array.prototype.includes 二.指数操作符 ES8新特性 一.async 和 await 1.async 函数 2.await 表达式 async和awa ...
- ES7、ES8、ES9、ES10、ES11新特性
一.ES7新特性 1. Array.prototype.includes includes 方法用来检测数组中是否包含某个元素,返回布尔值 2. 指数操作符 指数运算符 ** ,用来实现幂运算,功能与 ...
- 【复习资料】ES6/ES7/ES8/ES9资料整理(个人整理)
一.介绍 现在的网络上已经有各样关于 ECMAScript 规范介绍和分析的文章,而我自己重新学习一遍这些规范,整理出这么一份笔记,比较精简,主要内容涵盖ES6.ES7.ES8.ES9,后续会增加面试 ...
- es7,es8,es9新特性
es7,es8,es9新特性 1. ES7新特性(ECMAScript 2016) ES7在ES6的基础上主要添加了两项内容: Array.prototype.includes()方法 求幂运算符(* ...
- ES9,ES10,ES11知识点
目录 第 5 章 ECMASript 9 新特性 5.1. Rest/Spread 属性 5.2. 正则表达式命名捕获组 5.3. 正则表达式反向断言 5.4. 正则表达式 dotAll 模式 第 6 ...
- ECMAScript 2019(ES10) 的新特性总结
快速通道: ES6.ES7.ES8.ES9.ES10.ES11.ES12.ES13新特性大全 老规矩,先纵览下 ES2019 的新功能: Array.flat()和Array.flatMap():数组 ...
- 从ES6到ES10的新特性万字大总结
本文转自https://cloud.tencent.com/developer/article/1615505[作者:陈大鱼头•github: KRISACHAN[1]] 介绍 ECMAScript是 ...
最新文章
- KDD 2017奖项全公布,华人成最大赢家
- Makefile for OpenCV
- syslog-ng 正确配置udp接受端口
- 基于ArcSDE、Oralce空间数据库冷备份与恢复
- mysql 嵌套if标签_对比Excel、MySQL、Python,分别讲述 “if函数” 的使用原理!
- 需要gmail的朋友请留下你们的email,还有86个
- css3是什么 ptml_CSS3 @keyframes 规则
- AWS CSAA -- 04 AWS Object Storage and CDN - S3 Glacier and CloudFront(二)
- Emacs中打造强大的Python IDE
- php 时分秒转时分_php 时分秒转为秒,秒转化为天时分秒
- php ddos 防御,PHP DDos的几个防御方法详解
- matlab 加权残值法,分步迭代加权残值法
- Android ViewHolder的理解
- 一不小心画了 24 张图剖析计网应用层协议!
- 小学计算机小知识,小学生电脑基础知识
- 乐得瑞专门为笔记本/平板Type-C接口,HOST端解决方案
- 中南大学计算机复试分数线,2019年中南大学考研复试分数线
- html表格左右布局,css table布局大法,解决你大部分居中、多列等高、左右布局的问题...
- Qt之热敏打印机设置
- 埃森哲2021财年第三季度全球营收达133亿美元;富士胶片创新解决方案新成员亮相CHINA PRINT 2021 | 全球TMT...
热门文章