JS对象属性的继承与遍历

创建对象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

        }

    }

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容