在javascript中Object
含有很多内置函数,可能平时用的比较少,但是这些方法作用很大。这里对这些方法进行一些总结:
Object主要含有的方法包括:defineProperty(), defineProperties(), assign(), create(), entries(), freeze(), getOwnPropertyNames(), getPrototypeOf(), isExtensible(), isFrozen(), isSealed(), keys(), preventExtension(), seal()
Object原型中包含的方法:hasOwnProperty(), isPrototypeOf(), propertyIsEnumerable()
使用方式:Object.defineProperty(obj, prop, descriptor)
通过prop
定义对象属性,并通过描述符设置属性。描述符分为数据描述符和存取描述符。
数据描述符包括:
configurable 默认false,表示属性是否可以被改变或删除
enumerable 默认false,表示属性是否可以出现在对象的枚举属性中
writable 默认false,表示属性是否可以被赋值运算符改变
value 属性值
存取描述符包括:
get 属性的getter方法
set 属性的setter方法
如果我们给一个对象直接增加属性,像下面这样:
var obj = {};
obj.b = 2;
Object.getOwnPropertyDescriptor(obj,'b')
获取的结果是这样:
Object {value: 3, writable: true, enumerable: true, configurable: true}
如果一个属性的 configurable
为 false
,但是writable
改为true
,那么属性还是可以通过=
来修改属性,但是不能delete
,如:
var obj = {};
Object.defineProperty(obj, 'a', {
enumerable:false,//是否可枚举
configurable:false,//是否可修改
writable:true,//是否可赋值修改
value:'melo'
});
obj.a = 'meloseven';
delete obj.a;
console.dir(obj);
结果:
Object {a:'meloseven'}
如果enumerable
设为false
,那么在for...in
和Object.key()
中不能访问到
设置了configurable
不仅不能修改该属性,删除该属性,同时也不能用defineProperty()
来重新定义。注意:即使configurable和writable设为false,如果value的值是个对象,那么这个对象的属性(没有用defineProperty定义)是可以被修改的通过设置get和set可以改变对象赋值时的默认行为和获取值的默认返回。get和set不能与value同时使用,需要定义一个作用域来,比如:
function living(){
var self = this;
var isAlive = true;
Object.defineProperty(self, 'isAlive', {
get:function(){
return isAlive;
},
set:function(newValue){
isAlive = newValue;
}
});
self.kill = function(){
isAlive = false;
}
}
defineProperty()的批量方法
使用方法:Object.assign(target, ...sources)
将所有可枚举的属性的值从一个或多个源对象复制到目标对象
目前IE不支持
注意继承属性(通过for...in
可以获取到继承属性,通过hasOwnProperty
判断是否是继承属性,注意通过getOwnPropertyNames()
无法获取继承属性)和不可枚举属性(只能通过getOwnPropertyNames()
获取)无法被拷贝,如果源还有对象引用,那么目标对象同样也会保存引用。
针对深度拷贝,需要使用其他方法,因为 Object.assign() 拷贝的是属性值
example:
var x = {b:1};
var y = Object.assign({},x);
console.log(y);//{b:1},y与b没有引用关系
var x1 = {a:{b:3}};
var y1 = Object.assign({},x1);
y1.a.b = 5;
console.log(x1);//{a:{b:5}}
var x2 = Object.create(x1);
x2.c = {d:4};
var y2 = Object.assign({},x2);
console.log(y2);
y2.a.b = 7;//throw error. a无法拷贝
console.log(x2);
var x3 = Object.defineProperty({}, 'a', {
value:{
b:5
},
configurable:true,
writable:true,
enumerable:false
});
var y3 = Object.assign({},x3);
console.log(y3);//{}
var x4 = Object.defineProperty({}, 'a', {
value:5,
configurable:true,
writable:false,
enumerable:true
});
var y4 = Object.assign({},x4);
y4.a = 8;
console.log(y4);//{a:8}
var obj5 = {};
var x5 = Object.defineProperty(obj5, 'a', {
value:{
b:9
},
configurable:true,
writable:false,
enumerable:true
});
var y5 = Object.assign({},x5);
y5.a.b = 8;
console.log(y5);//{a:{b:8}}
console.log(x5);//{a:{b:8}}
使用方法:Object.create(proto, [ propertiesObject ])
使用指定的原型对象及其属性去创建一个新的对象.
propertiesObject
与defineProperties()的属性配置一致。
var a = Object.create(obj.prototype)
等同于
var a = {};
a.__proto__ = obj.prototype
后者不推荐使用
Object.keys()
方法会返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和使用 for...in
循环遍历该对象时返回的顺序一致 (两者的主要区别是 一个 for-in 循环还会枚举其原型链上的属性)。
Object.entries()
方法返回一个给定对象自己的可枚举属性[key,value]对的数组,数组中键值对的排列顺序和使用 for...in
循环遍历该对象时返回的顺序一致(区别在于一个for-in循环也枚举原型链中的属性)。