阅读 50

对象键名操作--小结

对象键名操作的三种姿势

  1. for…in...
  2. Object.keys()
  3. Object.getOwnPropertyNames();

姿势对比分析

1、for…in...

沿原型链遍历所有可枚举的属性key。

//父类
function ParentObj() {}
ParentObj.prototype.a = function() {};

//子类
function ChildObj() {
    this.b = 'hello b';
    //在子类上定义一个不可枚举,for...in...无法遍历得到;
    Object.defineProperty(this, 'm', {
        enumerable: false,
        value: 'the m is enumerable'
    })
    this.c = function() {};
}

//简易继承父类
ChildObj.prototype = new ParentObj();

//子类添加原型方法d
ChildObj.prototype.d = function() {};

//for...in...遍历验证
var keys = [];
for(var key in new ChildObj) {
	keys.push(key);
}
console.log(keys); 
// -> ['b','c','d','a'] 
//[注释] 可将子类中定义的m属性改为可枚举属性,结果是:['b','m','c','d','a']。可自行尝试.
复制代码

2、Object.keys()

遍历对象自身具有(非原型链上继承得来的)且可枚举的属性key。

//父类、子类创建及子类继承同1(上)
...

console.log(Object.keys(new ChildObj()));
//-> ['b','c']
//[注释] 可将子类中定义的m属性改为可枚举属性,结果是:['b','m','c']。可自行尝试.
复制代码

3、Object.getOwnPropertyNames()

遍历对象自身具有(非原型链上继承得来的)可枚举不可枚举的属性key。

//父类、子类创建及子类继承同1(上)
...

console.log(Object.getOwnPropertyNames(new ChildObj()));
//-> ['b','m','c']
复制代码

应用

1、用for…in…实现Object.keys()

//父类、子类创建及子类继承同1(上)
...

var keys = [];
var obj = new ChildObj;
for(var key in obj) {
    obj.hasOwnProperty(key) && keys.push(key);
}
console.log(keys);
//-> ['b', 'c']
//同 Object.keys(obj); -> ['b', 'c']

复制代码

2、获取一个对象自身中所有不可枚举的属性key

var obj = Object.create({}, {
    a: {
        enumerable: true,
        value: 1
    },
    b: {
        enumerable: false,
        value: 2
    },
    c: {
        enumerable: true,
        vaule: 3
    },
    d: {
        enumerable: false,
        value: 4
    }
});

var enumKeys = Object.keys(obj);
var enumNoenumKeys = Object.getOwnPropertyNames(obj);
var noenumKeys = enumNoenumKeys.filter((key) => {
	return enumKeys.indexOf(key) < 0;
})

console.log(noenumKeys); //-> ['b', 'd']
复制代码

参考链接

  1. 细说JavaScript中对象的属性和方法
  2. MDN——Object.getOwnPropertyNames()
评论