对象
object 方法
1.object.defineProperty
Object.defineProperty(obj,props)
- obj 在其上定义属性
- props 属性的描述符
- configurable: 属性是否可配置(指的是这个属性是否可以被删除和重新定义), 默认 false
- enumerable: 是否可枚举, 默认 false
- value: 属性值
- writable: 是否可写, 默认 false
- get: 读取属性值的时候调用的函数
- set: 设置属性值的时候调用的函数
var obj = {}
Object.defineProperties(obj, {
isAdmin: {
value: true,
writable: true,
},
name: {
value: 'John',
writable: false,
},
age: {
configurable: true,
writable: true,
value: 11,
},
// etc. etc.
})
Object.defineProperties(obj, {
name: {
value: 'Tom',
writable: false,
},
}) //报错 不能重新定义
Object.defineProperties(obj, {
age: {
value: 1000,
writable: false,
},
}) //报错 不能重新定义
// name 不可写
// age 可以删除, isAdmin和name 不能重新定义和删除
2.object.create
创建一个指定原型对象的对象,
Object.create(proto,[propertiesObject])
- proto 为新创建对象的原型
- propertiesObject 为新创建对象的属性
const person = {
proto: 'aaa',
}
const me = Object.create(person)
me.name = 'Matthew'
me.isHuman = true
let obj = Object.create(null)
//创建一个纯净对象
ES6 新增
属性简洁表示
ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。这样的书写更加简洁。
const obj = {
f() {
this.foo = 'bar'
},
}
可枚举性
对象的每个属性都有一个描述对象(Descriptor),用来控制该属性的行为。Object.getOwnPropertyDescriptor 方法可以获取该属性的描述对象。
let obj = { foo: 123 }
Object.getOwnPropertyDescriptor(obj, 'foo')
// {
// value: 123,
// writable: true,
// enumerable: true,
// configurable: true
// }
引入“可枚举”(enumerable)这个概念的最初目的,就是让某些属性可以规避掉 for...in 操作,不然所有内部属性和方法都会被遍历到。比如,对象原型的 toString 方法,以及数组的 length 属性,就通过“可枚举性”,从而避免被 for...in 遍历到。
Object.getOwnPropertyDescriptor(Object.prototype, 'toString').enumerable
// false
Object.getOwnPropertyDescriptor([], 'length').enumerable
// false
目前,有四个操作会忽略 enumerable 为 false 的属性。
- for...in 循环:只遍历对象自身的和继承的可枚举的属性。
- Object.keys():返回对象自身的所有可枚举的属性的键名。
- JSON.stringify():只串行化对象自身的可枚举的属性。
- Object.assign(): 忽略 enumerable 为 false 的属性,只拷贝对象自身的可枚举的属性。
属性的遍历
for..in..遍历
for...in 循环遍历对象自身的和继承的可枚举属性(不含 Symbol 属性)。
Object.keys()
返回一个数组,包括对象自身的(不含继承的)所有可枚举(不含 Symbol 属性的健名
Object.getOwnPropertyNames(obj)
Object.getOwnPropertyNames 返回一个数组,包含对象自身的所有属性(不含 Symbol 属性,但是包括不可枚举属性)的键名
Object.getOwnPropertySymbols(obj)
Object.getOwnPropertySymbols 返回一个数组,包含对象自身的所有 Symbol 属性的键名
Reflect.ownKeys(obj) Reflect.ownKeys 返回一个数组,包含对象自身的(不含继承的)所有键名,不管键名是 Symbol 或字符串,也不管是否可枚举。
以上的 5 种方法遍历对象的键名,都遵守同样的属性遍历的次序规则。
- 首先遍历所有数值键,按照数值升序排列。
- 其次遍历所有字符串键,按照加入时间升序排列。
- 最后遍历所有 Symbol 键,按照加入时间升序排列。
super
this 关键字总是指向函数所在的当前对象,ES6 又新增了另一个类似的关键字 super,指向当前对象的原型对象。
const proto = {
foo: 'hello',
}
const obj = {
foo: 'world',
find() {
return super.foo
},
}
Object.setPrototypeOf(obj, proto) //将obj的原型指向proto
obj.find() // "hello"
Object.is
ES6 提出“Same-value equality”(同值相等)算法,用来解决这个问题。Object.is 就是部署这个算法的新方法。它用来比较两个值是否严格相等,与严格比较运算符(===)的行为基本一致。 不同之处只有两个:一是+0 不等于-0,二是 NaN 等于自身。
Object.is('foo', 'foo')
// true
Object.is({}, {}) +
// false
0 ===
-0 //true
NaN === NaN // false
Object.is(+0, -0) // false
Object.is(NaN, NaN) // true
Object.assign
- 克隆对象
function clone(origin) {
let originProto = Object.getPrototypeOf(origin)
return Object.assign(Object.create(originProto), origin)
}
ES6 原型链
// es5 的写法
const obj = {
method: function() { ... }
};
obj.__proto__ = someOtherObj;
// es6 的写法
var obj = Object.create(someOtherObj);
obj.method = function() { ... };
Object.fromEntries()
Object.fromEntries()方法是 Object.entries()的逆操作,用于将一个键值对数组转为对象。 该方法的主要目的,是将键值对的数据结构还原为对象,因此特别适合将 Map 结构转为对象。
Object.fromEntries([
['foo', 'bar'],
['baz', 42],
])
// { foo: "bar", baz: 42 }