属性的拓展
属性的简介表示法
ES6允许直接写入变量和函数,作为对象的属性和方法。这样的书写更加简洁。let a = 1
let age={
a
}
console.log(age) //{a:1}除了属性可以简写之外,方法也可以简写
let f = {
foo(){}
}
//相当于
let f = {
foo:function () {}
}在函数返回值的时候,可以这样写
function add(x, y) {
let x = x + 1
let y = y + 1
return {
x,
y
}
}CommonJS模板输出一组变量,可以这样写function getItem(key) {
return obj[key]
}
function setItem(key, value) {
obj[key] = value
}
module.exports = {
getItem,
setItem
}属性的可枚举性与遍历
对象的每个属性都有一个描述对象(Descriptor),用来控制该属性的行为。
Object.getOwnPropertyDescriptor方法可以获取该属性的描述对象。let foo = {
age:20
}
Object.getOwnPropertyDescriptor(foo,'age')
//{
configurable: true,
enumerable: true,
value: 20
writable: true
}如果
enumerable属性为false,则不可以用以下方法来进行遍历for...in循环:只遍历对象自身的和继承的可枚举的属性。Object.keys():返回对象自身的所有可枚举的属性的键名。JSON.stringify():只串行化对象自身的可枚举的属性。Object.assign(): 忽略enumerable为false的属性,只拷贝对象自身的可枚举的属性。
遍历对象的方法
let symbol = Symbol()
let foo = {
age: 20,
name: 'David',
[symbol]: 'symbol'
}for...in
for...in循环遍历对象自身的和继承的可枚举属性(不含 Symbol 属性)。for (let i in foo) {
console.log(i) // age name
}Object.keys(obj)
Object.keys()返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含 Symbol 属性)的键名。Object.keys(foo).forEach(item => {
console.log(item) //age name
})Object.values(obj)
Objec.values()返回一个数组,包括对象自身(不含继承的)的所有可枚举属性的键值(不含Symbol属性)Object.values(foo).forEach(item => {
console.log(item) //20 David
})Object.getOwnPropertyNames(obj)
Object.getOwnPropertyNames()返回一个数组,包含对象自身的所有属性(不含 Symbol 属性,但是包括不可枚举属性)的键名。Object.getOwnPropertyNames(foo) //['age','name']Object.getOwnPropertySymbols(obj)
Object.getOwnPropertySymbols()返回一个数组,包含对象自身的所有 Symbol 属性的键名。Object.getOwnPropertySymbols(foo) //[Symbol()]Reflect.ownKeys(obj)
Reflect.ownKeys()返回一个数组,包含对象自身的所有键名,不管键名是 Symbol 或字符串,也不管是否可枚举。Reflect.ownKeys(foo) //[ 'age', 'name', Symbol() ]对象的新增方法
Object.is()
ES6 提出“Same-value equality”(同值相等)算法,用来解决这个问题。Object.is就是部署这个算法的新方法。它用来比较两个值是否严格相等,与严格比较运算符(===)的行为基本一致。
Object.is('foo', 'foo'), //true
Object.is(+0, -0), //false
Object.is(NaN, NaN), //true
Object.is([], []) //false不同之处只有两个:一是
+0不等于-0,二是NaN等于自身。Object.assign()
Object.assign()方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)。let target = {
a: 1
}
let source1 = {
b: 2
}
let source2 = {
c: 3
}
target //{ a: 1, b: 2, c: 3 }但是
Object.assign()方法实行的是浅拷贝,如果源对象某个属性的值是对象,那么目标对象拷贝得到的是这个对象的引用。Object.getOwnPropertyDescriptors()
ES5 的Object.getOwnPropertyDescriptor()方法会返回某个对象属性的描述对象(descriptor)。ES2017 引入了Object.getOwnPropertyDescriptors()方法,返回指定对象所有自身属性(非继承属性)的描述对象。
let obj = {
age: 20,
name: 'David'
}
Object.getOwnPropertyDescriptor(obj, 'age')
//{
value: 20,
writable: true,
enumerable: true,
configurable: true
}
Object.getOwnPropertyDescriptors(obj)
{
age:{
value: 20,
writable: true,
enumerable: true,
configurable: true
},
name:{
value: 'David',
writable: true,
enumerable: true,
configurable: true
}
}
__proto__属性、Object.setPrototypeOf()、Object.getPrototypeOf()
JavaScript语言的对象继承是通过原型链实现的。ES6 提供了更多原型对象的操作方法。
__proto__属性__proto__属性(前后各两个下划线),用来读取或设置当前对象的prototype对象。 const obj = {
method: function() { ... }
};
obj.__proto__ = someOtherObj;Object.setPrototypeOf()
Object.setPrototypeOf()方法的作用与__proto__相同,用来设置一个对象的prototype对象,返回参数对象本身
Object.setPrototypeOf(obj,someOtherObj)Object.getPrototypeOf()
该方法与
Object.setPrototypeOf()方法配套,用于读取一个对象的原型对象。Object.getPrototypeOf(obj)Object.entries()
Object.entries()方法返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值对数组。Object.entries(foo) //[ [ 'age', 20 ], [ 'name', 'David' ] ]Object.fromEntries()
Object.fromEntries()方法是Object.entries()的逆操作,用于将一个键值对数组转为对象。Object.fromEntries([
['age', 20],
['name', 'David']
])
//{age:20,name:'David'}