属性的拓展
属性的简介表示法
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'}