创建对象foo,并在其原型上声明属性x,enumerable值为true,value值为1。
function foo(){}
Object.defineProperty(foo.prototype,'x',{enumerable: true, value: 1});
用 Object.create(object) 创建对象obj,使其原型指向对象foo的实例,打印obj发现是空对象,但是打印obj.x却有值。这是为什么呢?其实一开始先在自身查找是否存在指定属性,没有的话会继续往上找,也就是在原型上找,找到则停止,找不到最后则返回null。
我们也可以用 Object.hasOwnProperty(prop) 查看对象自身属性中是否具有指定的属性,如果在对象自身则返回true,反之返回false。
ps:in操作符能找到原型链上的属性。
var obj = Object.create(new foo());
console.log(obj); //foo {}
console.log(obj.x); //1
console.log('x' in obj); //true
console.log(obj.hasOwnProperty('x')); //false
1、对象属性的继承。
下面的实例修改之后x的值还是为1,原因是在foo原型定义的x的writable默认为false,即只能读取,不能修改。
console.log(obj.x); //1
obj.x = 5; //修改x的值
console.log(obj.x); //1
我们重新修改一下原型的x属性,可以看到这次x变成5了,不过他只是在自身创建了个x属性,不用原型的x了,我们可以通过obj.hasOwnProperty('x')知道,然后delete掉对象自身的x,再打印,x为原型上的属性,值为1,这就是原型链的继承。我们可以继承原型上的属性,同时也不会修改到它。
Object.defineProperty(foo.prototype,'x',{enumerable: true, writable: true, value: 1});
console.log(obj.x); //1
obj.x = 5; //修改x的值
console.log(obj.x); //5
delete obj.x; //这里删除自身的x
console.log(obj.x); //这里是原型上的x
2、对象属性的遍历
用 Object.defineProperties(obj,props) 在对象obj上定义新的属性name和type。
ps: enumerable:是否可遍历,由于type上设置了false,所以后面遍历的时候没有打印type
Object.defineProperties(obj , {
name: {value: 'Ann', enumerable: true},
type: {value: 'Object', enumerable: false, writable: true}
});
用Object.keys()和for...in...遍历查看obj的键名,比较一下这两种方法
Object.keys(obj) //["name"]
for(var key in obj){
console.log(key); // name,x
}
为什么两种写法结果不同呢?
Object.keys()只能遍历对象自身的属性,
for...in...能遍历原型上面扩展的属性,并且顺序不确定,在使用时得注意!
我们可以用Object.hasOwnProperty(prop) 加个判断,改写一下for...in...,让他只能遍历自身的属性。
for(var key in obj){
if(obj.hasOwnProperty(key)){
console.log(key); //name
}
}