JavaScript对象详解
Object.create
Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。Object.create()是一个静态函数,而不是提供给某个对象调用的方法。
语法
Object.create(proto, [propertiesObject])
参数
- proto:新创建对象的原型对象。
- 可选。如果没有指定为 undefined,则是要添加到新创建对象的可枚举属性(即其自身定义的属性,而不是其原型链上的枚举属性)对象的属性描述符以及相应的属性名称。这些属性对应Object.defineProperties()的第二个参数。
返回值
一个新对象,带着指定的原型对象和属性。
**如果propertiesObject参数是 null 或非原始包装对象,则抛出一个 TypeError 异常。
**
例子
使用
object.create
实现类继承
function Prent(){
this.a = 1
}
Prent.prototype.add = function(){
console.log(this)
}
function Child(){
Prent.call(this)
}
Child.prototype = Object.create(Prent.prototype)
Child.prototype.constructor = Child;
let child = new Child();
console.log(child)
Object.assign
Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。
语法
Object.assign(target, ...sources)
参数
- target:目标对象
- 源对象。
返回值
- 目标对象
注意
如果目标对象中的属性具有相同的键,则属性将被源对象中的属性覆盖。后面的源对象的属性将类似地覆盖前面的源对象的属性。Object.assign 方法只会拷贝源对象自身的并且可枚举的属性到目标对象。该方法使用源对象的[[Get]]和目标对象的[[Set]],所以它会调用相关 getter 和 setter。因此,它分配属性,而不仅仅是复制或定义新的属性。
例子
- 合并对象
let a = {
a:1
}
let b = {
b:2
}
let c = Object.assign(a,b);
console.log(c); // {a: 1, b: 2}
- 拷贝对象
let a = {
a:1
}
let c = Object.assign({},a);
console.log(c); // {a: 1}
- 深拷贝问题
针对深拷贝,需要使用其他办法,因为 Object.assign()拷贝的是属性值。假如源对象的属性值是一个对象的引用,那么它也只指向那个引用。
let a = {
b:{
name:1
}
}
a.b.name = 2;
let c = Object.assign({},a);
console.log(c.b); // {name: 2}
- 合并相同属性的对象
let obj1 = {a:1,b:1,c:1}
let obj2 = {b:2,c:2}
let obj3 = {c:3}
let newObje = Object.assign({},obj1,obj2,obj3)
console.log(newObje) // {a: 1, b: 2, c: 3}
Object.defineProperties
Object.defineProperties() 方法直接在一个对象上定义新的属性或修改现有属性,并返回该对象。
语法
Object.defineProperties(obj, props)
参数
- obj: 在其上定义或修改属性的对象。
- props:要定义其可枚举属性或修改的属性描述符的对象。对象中存在的属性描述符主要有两种:数据描述符和访问器描述符.描述符具有以下键:
- configurable:
true
当且仅当该属性描述符的类型可以被改变并且该属性可以从对应对象中删除。
默认为false
- enumerable:
true
当且仅当在枚举相应对象上的属性时该属性显现。
默认为false
- value:与属性关联的值。可以是任何有效的JavaScript值(数字,对象,函数等)。默认为
undefined
- writable:
true
当且仅当与该属性相关联的值可以用assignment operator改变时。
默认为false
- get:作为该属性的 getter 函数,如果没有 getter 则为undefined。函数返回值将被用作属性的值。默认为
undefined
- 作为属性的 setter 函数,如果没有 setter 则为undefined。函数将仅接受参数赋值给该属性的新值。默认值
undefined
.
- configurable:
返回值
传递给函数的对象
例子
let obj = {}
Object.defineProperties(obj,{
"name":{
value:'hah',
writable:true
}
})
console.log(obj) // {name: "hah"}
Object.defineProperty
Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。
语法
Object.defineProperty(obj, prop, descriptor)
参数
- obj:要在其上定义属性的对象。
- 要定义或修改的属性的名称。
- 将被定义或修改的属性描述符。
例子
- 在对象中添加一个属性与存取描述符的示例
let obj = {};
let val;
Object.defineProperty(obj,'a',{
get(){
return val
},
set(value){
console.log(value) // 2
val = value
}
})
obj.a = 2;
Object.entries
Object.entries()方法返回一个给定对象自身可枚举属性的键值对数组,其排列与使用 for...in 循环遍历该对象时返回的顺序一致(区别在于 for-in 循环也枚举原型链中的属性)
语法
Object.entries(obj)
参数
- obj:可以返回其可枚举属性的键值对的对象
返回值
给定对象自身可枚举属性的键值对数组。
例子
let obj = {
name:1,
age:2
}
console.log(Object.entries(obj)) // [Array(2), Array(2)]
// 0: ["name", 1]
// 1: ["age", 2]
Object.freeze
Object.freeze() 方法可以冻结一个对象。一个被冻结的对象再也不能被修改;冻结了一个对象则不能向这个对象添加新的属性,不能删除已有属性,不能修改该对象已有属性的可枚举性、可配置性、可写性,以及不能修改已有属性的值。此外,冻结一个对象后该对象的原型也不能被修改。freeze() 返回和传入的参数相同的对象。
语法
Object.freeze(obj)
参数
- obj:要冻结的对象
返回值
- 被冻结的对象
例子
let obj = {
fn(){},
prop:1
}
// 现在任何改变都会失效
let newObj = Object.freeze(obj)
obj.prop = 2;
console.log(newObj === obj) // true
console.log(obj) // {fn: ƒ, prop: 1}
Object.fromEntrie
Object.fromEntries() 方法把键值对列表转换为一个对象。方法接收一个键值对的列表参数,并返回一个带有这些键值对的新对象。这个迭代参数应该是一个能够实现@iterator方法的的对象,返回一个迭代器对象。它生成一个具有两个元素的类数组的对象,第一个元素是将用作属性键的值,第二个元素是与该属性键关联的值。
Object.fromEntries() 是 Object.entries 的反转。
语法
Object.fromEntries(iterable);
参数
- iterable:可迭代对象,类似 Array 、 Map 或者其它实现了可迭代协议的对象。
返回值
一个由该迭代对象条目提供对应属性的新对象。
例子
- Map 转 Object
const map = new Map([ ['foo', 'bar'], ['baz', 42] ]);
let obj = Object.fromEntries(map)
console.log(obj) // {foo: "bar", baz: 42}
- 对象转换
let obj = {a:1,b:2}
let newObj = Object.fromEntries(Object.entries(obj).map(([key,val])=>[key,val * 2]))
console.log(newObj) // {a: 2, b: 4}