Object.prototype.propertyIsEnumerable()
//判断某个属性是否可以遍历,只能判断实例对象本身属性,不可枚举属性以及继承而来的属性一律为false
//可枚举:可以遍历的属性
var obj = {};
obj.a =123;
console.log(obj.propertyIsEnumerable('a'));//true
console.log(obj.propertyIsEnumerable('toString'));//false
for(var key in obj){
console.log(key);//a
console.log(obj[key]);//123
}
var arr = [1, 2, 3];
console.log(arr.propertyIsEnumerable('length'));//false
getOwnPropertyDescription()
//可以获取属性描述对象,它的第一个参数是目标对象,第二个参数是一个字符串(目标对象的属性名)
var arr = [1,23,4];
console.log(arr['length']);
console.log(Object.getOwnPropertyDescriptor(arr,'0'));
/*{value: 1, writable: true, enumerable: true, configurable: true}
configurable: true
enumerable: true
value: 1
writable: true
__proto__: Object */
console.log(Object.getOwnPropertyDescriptor(arr,'length'));
/*{value: 3, writable: true, enumerable: false, configurable: false}
configurable: false 可配置型 false为不可被删除
enumerable: false 不能被遍历出来
value: 3
writable: true 可以被读写
__proto__: Object */
console.log(Object.getOwnPropertyDescriptor(arr,'toString'));//undefined
//不能用于继承的属性 只能用于对象自身的属
/Objcet.defineProperty()
//Objcet.defineProperty(属性所在的对象,属性名,属性描述对象)
var obj = Object.defineProperty({},'name',{
value:'qaq',
writable:false, //可写性
enumrable:true, //可遍历
configurable:false, //是否能被删除
})
console.log(obj);
obj.name = 'aaa';
console.log(obj.name);//qaq
delete obj.name;
console.log(obj.name);//qaq
Object.defineProperties()
var obj = Object.defineProperties({},{
p1:{
value:1,
enumerable:true
},
p2:{
value:'qaq',
enumerable:false
},
p3:{
get:function(){
return this.p1 + this.p2
},//value与get不能同时存在
enumerable:true,
configurable:true
}
})
console.log(obj);
/*{p1: 1, p2: 2}
p1: 1
p3: "1qaq"
p2: "qaq"
get p3: ƒ () */
//一旦定义了取值函数get,就不能同时定义writable以及value
var obj2 = Object.defineProperty({},'a',{
writable:true,
get : function(){
return 111;
}
})
console.log(obj2.a);//报错
value、writable
//value
var obj = {};
obj.p = 123;
console.log(Object.getOwnPropertyDescriptor(obj,'p').value);//123
Object.defineProperty(obj,'p',{value : 456});
console.log(obj.p);//456
//writable 是否可以改变
var obj = {};
obj.p = 123;
Object.defineProperty(obj,'p',{
value:890,
writable:false
});
console.log(obj.p);//890
obj.p = 100;
console.log(obj.p);//89
enumrable、defineProperties
enumrable可遍历性,一旦enumrable设置为false,通常以下三个操作不会取到该属性。for...in、Object.keys()、JSON.stringify()。
ps:继承来的属性是可以被这三个操作取到的
configurable 可配置性,决定是否可以修改属性描述对象。
一旦设置configurable为false,属性描述对象 value、writable、enumable、configurable都不能被修改
特殊情况
- 在configurable为false情况下,writable从true改成false是可行的
- 只要writable和configurable有一个为true,value就允许被修改
- configurable一旦设置了true 属性可被删除,false不可被删除
深拷贝,浅拷贝
- 浅拷贝:与深拷贝相反,有影响的为浅拷贝
本质上不是直接赋值,浅拷贝新建了一个对象,将原来对象的属性都一一的复制过来,复制的是指,不是引用。浅拷贝的复制只复制了第一层的属性,并没有递归所有的值复制归来。例如一个对象中的数组(对象),只复制了数组(对象) 没有吧数组(对象)里的值复制过来 - 深拷贝:操作拷贝之后的对象的某个属性不会影响原始对象的属性,这种拷贝是深拷贝。
本质上深拷贝对目标对象完全拷贝,不像浅拷贝那样只是复制了一层引用,就连值也复制过来。只要进行了深拷贝,两者便老死不相往来,谁也不影响谁。