1、Object.assign(target,source1,source2,...)
主要用于对象的合并,将源对象source的所有可枚举属性合并到目标对象target上
- 只拷贝源对象的自身属性,不拷贝继承(原型上)的属性,同名属性会替换。
- 实行的是浅拷贝,而不是深拷贝。也就是说,如果源对象某个属性的值是对象,那么目标对象拷贝得到的是这个对象的引用。
- 进行值的复制,如果要复制的值是一个取值函数,那么将求值后再复制。
- 可以用来处理数组,但是会把数组视为对象
const target = {
x : 0,
y : 1
};
const source = {
x : 1,
z : 2 ,
fn : {
number : 1
}
};
Object.assign(target, source);
// target {x : 1, y : 1, z : 2, fn : {number : 1}} // 同名属性会被覆盖
// source {x : 1, z : 2, fn : {number : 1}}
target.fn.number = 2; // 拷贝为对象引用
// source {x : 1, z : 2, fn : {number : 2}}
function Person(){
this.name = 1
};
Person.prototype.country = 'china';
let student = new Person();
student.age = 29 ;
const young = {insterst : 'sport'};
Object.assign(young,student);
// young {instest : 'sport' , age : 29, name: 1} // 只能拷贝自身的属性,不能拷贝prototype
Object.assign([1, 2, 3], [4, 5]) // 把数组当作对象来处理
// [4, 5, 3]
2、Object.create(proto[, propertiesObject])
该方法创建一个新对象,使用现有的对象来提供新创建的对象的proto
- proto:必须。新创建对象的原型对象,即通过 Object.create()生成的对象的原型 指向 proto(可以是 null、对象、函数的 prototype 属性),设置原型对象的属性和方法。
(注:创建空原型的对象时需传 null , 否则会抛出 TypeError 异常)。 - propertiesObjec:可选。 添加到新创建对象的可枚举属性(即其自身的属性,而不是原型链上的枚举属性)对象的属性描述符以及相应的属性名称。这些属性对应 Object.defineProperties()的第二个参数。
- 返回值:一个新对象,带着指定的原型对象和属性。
var parent = {
x : 1,
y : 1
}
var child = Object.create(parent,{
z : {
writable:true,
configurable:true,
value: "newAdd"
}
});
console.log(child)
console.log(Object.getPrototypeOf(child)) // {x: 1, y: 1}
new Object() 和 Object.create()比较
1、对象创建方式
- new Object(obj) :通过构造函数的对象, 对象添加的属性 obj 是在自身实例下
const org = {
type: 'human'
}
var Obj = new Object(org)
console.log(Obj) // { type: 'human' }
console.log(Obj.__proto__) // {} -> built-in
console.log(Obj.type) // human
- Object.create(proto[, propertiesObject]) :创建的新对象继承一个对象。 添加的属性 proto 是在原型下,添加的属性 propertiesObject 才在自身实例下
var ObjCre = Object.create(org, { name: { value: "JyLie" } })
console.log(ObjCre) // {name: 'JyLie'}
console.log(ObjCre.__proto__) // { type: 'human' }
console.log(ObjCre.type) // human
2、创建空对象时,是否有原型属性
- Object.create(null)创建空对象,新对象是没有原型属性的
Object.create(null) // {} 没有原型对象的空对象。纯空对象。
- 构造函数或对象字面量方法创建空对象时,新对象有原型属性(built-in)
new Object() // {} 拥有built-in
3、对象属性描述符
- 通过 Object.create 第二个参数创建非空对象的属性描述符默认是为 false 的,不可写,不可枚举,不可配置
3、Object.entries() 和 Object.fromEntries()
Object.entries()
返回一个给定对象自身可枚举属性的键值对数组,其排列与使用 for…in 循环遍历该对象时返回的顺序一致(区别在于 for-in 循环还会枚举原型链中的属性)
Object.fromEntries()
方法把键值对列表转换为一个对象。
const object1 = {
a: 'somestring',
b: 42,
c: {
d: true,
e: 22
}
};
let attr = Object.entries(object1)
console.log(attr);//[['a': 'somestring'],['b': 42],['c',{d: true, e: 22}]]
for (let [key, value] of attr) {
console.log(`${key}: ${value}`);
// a: somestring
// b: 42
// c: [object Object]
}
let obj = Object.fromEntries(attr)
console.log(obj) // {a: "somestring", b: 42, c: {{d: true, e: 22}}}
4、Object.defineProperty()
会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性并指定该属性的配置,并返回此对象。
Object.defineProperty(obj, prop, descriptor)
- obj 要定义属性的对象
- prop 要定义或修改的属性的名称或 Symbol
- descriptor 要定义或修改的属性描述符,如果不设置属性的特性,那么configurable、enumerable、writable这些值都为默认的false
-
属性描述符
数据描述符和存取描述符不能同时是两者,如果一个描述符同时拥有 value 或 writable 和 get 或 set 键,则会产生一个异常。(因为get和set设置的时候js会忽略value和writable的特性)
公用
configurable
默认为 false
。
是否可以删除目标属性或是否可以再次修改属性的特性( writable
, configurable
, enumerable
)。设置为true
可以被删除或可以重新设置特性;设置为false
,不能被可以被删除或不可以重新设置特性。
var o = {}; // 创建一个新对象
Object.defineProperty(o, 'a', {
configurable:false,
value:1
});
console.log(o.a); // 1
delete o.a ;
console.log(o.a); // 1
Object.defineProperty(o, 'b', {
configurable:true,
value:1
});
console.log(o.b); // 1
delete o.b ;
console.log(o.b); // undefined
enumerable
默认为 false
此属性是否可以被枚举(使用for...in或Object.keys())。设置为true可以被枚举;设置为false,不能被枚举。默认为false。
var o = {};
Object.defineProperty(o, 'a', {
value: 1,
enumerable:true,
configurable:true
});
Object.defineProperty(o, 'b', {
value: 2,
enumerable:true
});
Object.defineProperty(o, 'c', {
value: 3
//默认enumerable为false
});
o.d = 4; // 如果使用直接赋值的方式创建对象的属性,则 enumerable 为 true
for (const key in o) {
console.log('1',key); // a b d
}
数据描述符
value
默认 undefined
该属性对应的值。
writable
默认为 false
属性的值value
是否可以被重写。设置为true可以被重写;设置为false,不能被重写。
var o = {}; // 创建一个新对象
// 在对象中添加一个属性与数据描述符的示例
Object.defineProperty(o, 'a', {
value : 30,
writable : true,
enumerable : true,
configurable : true
});
console.log(o.a) // 30
Object.defineProperty(o, 'a', {
value: 30,
writable: false
});
o.a = 40;
console.log(o.a); // 30 无法修改
存取描述符
get
默认为 undefined
属性的 getter
函数,如果没有 getter
,则为 undefined
。当访问该属性时,会调用此函数。执行时不传入任何参数,但是会传入 this
对象(由于继承关系,这里的this
并不一定是定义该属性的对象)。该函数的返回值会被用作属性的值。
set
默认为 undefined
属性的 setter
函数,如果没有 setter
,则为 undefined
。当属性值被修改时,会调用此函数。该方法接受一个参数(也就是被赋予的新值),会传入赋值时的 this
对象。
var o = {}; // 创建一个新对象
var value;
Object.defineProperty(o, "a", {
enumerable: true,
configurable: true,
get() {
return value
},
set(newvalue) {
console.log('newvalue',newvalue)
value = newvalue;
}
});
console.log(o.a) // undefined
o.a=1; // 触发set特性 打印 newvalue 1
console.log(o.a) // 1
5、Object.defineProperties()
给对象添加多个属性并分别指定它们的配置。
Object.defineProperties(obj, props)
- obj
在其上定义或修改属性的对象。 - props
要定义其可枚举属性或修改的属性描述符的对象。
var obj = {};
Object.defineProperties(obj, {
'property1': {
value: 30,
writable: true
},
'property2': {
value: 'xxx',
writable: false
}
});
6、Object.keys() 和 Object.values()
Object.keys()
:返回一个由给定对象的自身可枚举属性
组成的数组,不包括原型链上的可枚举属性
Object.values()
:返回一个由给定对象的自身可枚举属性值
组成的数组,不包括原型链上的可枚举属性值
for...in
循环是 遍历对象的每一个可枚举属性,包括原型链上面的可枚举属性,
const object1 = {
a: 'somestring',
b: 42
};
console.log(Object.keys(object1)) // ["a", "b"]
console.log(Object.values(object1)) // ["somestring", 42]
7、Object.getOwnPropertyNames(obj)
返回一个数组,包含对象自身的所有属性(不含 Symbol 属性,不包括原型链上面的,但是包括不可枚举属性)的键名
8、Object.getOwnPropertySymbols(obj)
返回一个数组,包含对象自身的所有 Symbol 属性的键名
9、Reflect.ownKeys(obj)
返回一个数组,包含对象自身的所有键名,不管键名是 Symbol 或字符串,也不管是否可枚举