ES7在ES6的基础上添加了三项内容:
- 求幂运算符(**)
- Array.prototype.includes()方法
- 函数作用域中严格模式的变更
Array.prototype.includes()方法
Array.prototype.includes()方法接收两个参数:要搜索的值和搜索的开始索引。当第二个参数被传入时,该方法会从索引处开始往后搜索(默认索引值为0)。若搜索值在数组中存在则返回true,否则返回false。 且看下面示例:
['a', 'b', 'c', 'd'].includes('b') // true
['a', 'b', 'c', 'd'].includes('b', 1) // true
['a', 'b', 'c', 'd'].includes('b', 2) // false
ES6里数组的另一个方法indexOf,下面的示例代码是等效的:
['a', 'b', 'c'].includes('a') //true
['a', 'b', 'c'].indexOf('a') > -1 //true
两者使用的都是 === 操作符来做值的比较。但是includes()方法有一点不同,两个NaN被认为是相等的,即使在NaN === NaN结果是false的情况下。这一点和indexOf()的行为不同,indexOf()严格使用===判断。请看下面示例代码:
let demo = [1, NaN, 2, 3]
demo.indexOf(NaN) //-1
demo.includes(NaN) //true
场景处理:
假如你只想知道某个值是否在数组中而并不关心它的索引位置,建议使用includes()。如果你想获取一个值在数组中的位置,那么你只能使用indexOf方法。
注意:
在这里,需要注意一点,includes()只能判断简单类型的数据,对于复杂类型的数据,比如对象类型的数组,二维数组,这些,是无法判断的。
['a', 'b', 'c',[11,22,333]].includes([11,22,333]); // false
求幂运算符(**)
基本用法
3 ** 2 // 9
效果同ES5写法:
Math.pow(3, 2) // 9
举例:
let a = 3
a **= 2
//9
Object.entries()
如果一个对象是具有键值对的数据结构,则每一个键值对都将会编译成一个具有两个元素的数组,这些数组最终会放到一个数组中,返回一个二维数组。简言之,该方法会将某个对象的可枚举属性与值按照二维数组的方式返回。若目标对象是数组时,则会将数组的下标作为键值返回。
Object.entries({ one: 1, two: 2 }) //[['one', 1], ['two', 2]]
Object.entries([1, 2]) //[['0', 1], ['1', 2]]
如果键的值是Symbol,编译时将会被忽略。例如:
Object.entries({ [Symbol()]: 1, two: 2 }) //[['two', 2]]
Object.values()
它的工作原理跟Object.entries()很像,顾名思义,它只返回自己的键值对中属性的值。它返回的数组顺序,也跟Object.entries()保持一致。
Object.values({ one: 1, two: 2 }) //[1, 2]
Object.values({ 3: 'a', 4: 'b', 1: 'c' }) //['c', 'a', 'b']
Object.keys()
在实际开发中,我们有时需要知道对象的所有属性,原生js给我们提供了一个很好的方法:Object.keys(),该方法返回一个数组
var obj = {'a':'123','b':'345'};
console.log(Object.keys(obj)); //['a','b']
Object.getOwnPropertyDescriptors()
该方法会返回目标对象中所有属性的属性描述符,该属性必须是对象自己定义的,不能是从原型链继承来的。先来看个它的基本用法:
const obj = {
id: 1,
name: 'test',
get gender() {
console.log('gender')
},
set grade(g) {
console.log(g)
}
}
Object.getOwnPropertyDescriptors(obj);
/***输出结果为***/
{
gender: {
configurable: true,
enumerable: true,
get: f gender(),
set: undefined
},
grade: {
configurable: true,
enumerable: true,
get: undefined,
set: f grade(g)
},
id: {
configurable: true,
enumerable: true,
value: 1,
writable: true
},
name: {
configurable: true,
enumerable: true,
value: 'test',
writable: true
}
}
方法还提供了第二个参数,用来获取指定属性的属性描述符。
let obj = {
id: 1,
name: 'test',
get gender() {
console.log('gender')
},
set grade(g) {
console.log(g)
}
}
Object.getOwnPropertyDescriptors(obj, 'id')
//输出结果为:
{
id: {
configurable: true,
enumerable: true,
value: 1,
writable: true
}
}
该方法返回的描述符,会有两种类型:数据描述符、存取器描述符。返回结果中包含的键可能的值有:configurable、enumerable、value、writable、get、set。
Object.getOwnPropertyDescriptors() 存在的意义
使用过Object.assign()的同学都知道,assign方法只能拷贝一个属性的值,而不会拷贝它背后的复制方法和取值方法。Object.getOwnPropertyDescriptors()主要是为了解决Object.assign()无法正确拷贝get属性和set属性的问题。
Object.assign() 拷贝
let obj = {
id: 1,
name: 'test',
get gender() {
console.log('gender')
}
}
Object.assign(obj)
//输出结果为:
{
gender: undefined
id: 1,
name: 'test'
}
Object.getOwnPropertyDescriptors() 拷贝
实现方式: Object.getOwnPropertyDescriptors 方法配合 Object.defineProperties 方法,就可以实现正确拷贝。
- EP one:
let obj = {
id: 1,
name: 'test',
get gender() {
console.log('gender')
}
}
let obj1 = {}
Object.defineProperties(obj1, Object.getOwnPropertyDescriptors(obj))
Object.getOwnPropertyDescriptors(obj1)
//输出结果为:
{
gender: {
configurable: true,
enumerable: true,
get: f gender(),
set: undefined
},
id: {
configurable: true,
enumerable: true,
value: 1,
writable: true
},
name: {
configurable: true,
enumerable: true,
value: 'test',
writable: true
}
}
- EP two:
const source = {
set foo(value) {
console.log(value);
}
};
const target2 = {};
Object.defineProperties(target2, Object.getOwnPropertyDescriptors(source));
Object.getOwnPropertyDescriptor(target2, 'foo');
// { get: undefined,
// set: [Function: set foo],
// enumerable: true,
// configurable: true }
参考地址:
- 大转转FE:
https://www.cnblogs.com/zhuanzhuanfe/p/7493433.html - 浅谈Object.getOwnPropertyDescriptors:
https://blog.csdn.net/qs8lk88/article/details/79024709 - ES6:http://www.ecma-international.org/ecma-262/6.0/index.html
- ES7:http://www.ecma-international.org/ecma-262/7.0/index.html
- ES8:http://www.ecma-international.org/ecma-262/8.0/index.html
- TC39提案:https://github.com/tc39/ecma262
- JS之父 ES7 ES8视频教程: https://node.university/p/es7-es8