定义:
方法会返回一个由一个给定对象的自身可枚举属性组成的数组,数组中
属性名的排列顺序和使用 for...in 循环遍历该对象时返回的顺序一致 。
复制代码
那我们先来看下 for ... in的用法
var obj = {
{ name: zhangsan },
{ name: lisi },
{ name: wangwu }
for (var i in obj) {
console.log(i) // "1" "2" "3"
console.log(typeof i) // string
console.log(obj[i].name) // "zhangsan" "lisi" "wangwu"
}
// the same
Object.keys(obj) // ["1","2","3"] ES5 or ES2015
}
复制代码
再看几个Array.keys的例子
// simple array
var arr = ['a', 'b', 'c'];
console.log(Object.keys(arr)); // console: ['0', '1', '2']
// array like object
var obj = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.keys(obj)); // console: ['0', '1', '2']
// array like object with random key ordering
var anObj = { 100: 'a', 2: 'b', 7: 'c' };
console.log(Object.keys(anObj)); // console: ['2', '7', '100']
// getFoo is a property which is not enumerable
var myObj = Object.create({}, {
getFoo: {
value: function () { return this.foo; }
}
});
myObj.foo = 1;
console.log(Object.keys(myObj)); // console: ['foo']
复制代码
注意:
在ES5里,如果此方法的参数不是对象(而是一个原始值),那么它会抛出 TypeError。在ES2015中,非对象的参数将被强制转换为一个对象。
Object.keys("foo");
// TypeError: "foo" is not an object (ES5 code)
Object.keys("foo");
// ["0", "1", "2"] (ES2015 code)
复制代码
针对上面,还有要兼容较低版本的浏览器,我们必须要添加兼容支持Object.keys的方法
if (!Object.keys) {
Object.keys = (function () {
var hasOwnProperty = Object.prototype.hasOwnProperty,
hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'),
dontEnums = [
'toString',
'toLocaleString',
'valueOf',
'hasOwnProperty',
'isPrototypeOf',
'propertyIsEnumerable',
'constructor'
],
dontEnumsLength = dontEnums.length;
return function (obj) {
if (typeof obj !== 'object' && typeof obj !== 'function' || obj === null) throw new TypeError('Object.keys called on non-object');
var result = [];
for (var prop in obj) {
if (hasOwnProperty.call(obj, prop)) result.push(prop);
}
if (hasDontEnumBug) {
for (var i=0; i < dontEnumsLength; i++) {
if (hasOwnProperty.call(obj, dontEnums[i])) result.push(dontEnums[i]);
}
}
return result;
}
})()
};
复制代码
上面的代码在IE7(也许IE8也是)下有个问题,就是如果传入一个来自其他 window 对象下的对象时,不可枚举的属性也会获取到。
扩展:Object.getOwnPropertyNames()
Object.getOwnPropertyNames()方法返回一个由指定对象的所有自身属性的属
性名(包括不可枚举属性但不包括Symbol值作为名称的属性)组成的数组。
复制代码
var arr = ["a", "b", "c"];
console.log(Object.getOwnPropertyNames(arr).sort()); // ["0", "1", "2", "length"]
console.log(Object.keys(arr); // ["0", "1", "2"]
复制代码
// 类数组对象
var obj = { 1: "a", 3: "b", 2: "c"};
console.log(Object.getOwnPropertyNames(obj).sort()); // ["0", "1", "2"]
// "the same"
console.log(Object.keys(arr); // ["0", "1", "2"]
复制代码
// 使用Array.forEach输出属性名和属性值
Object.getOwnPropertyNames(obj).forEach(function(val, idx, array) {
console.log(val + " -> " + obj[val]);
});
// 输出
// 0 -> a
// 1 -> b
// 2 -> c
//不可枚举属性
var my_obj = Object.create({}, {
getFoo: {
value: function() { return this.foo; },
enumerable: false
}
});
my_obj.foo = 1;
console.log(Object.getOwnPropertyNames(my_obj).sort()); // ["foo", "getFoo"]
复制代码
扩展:hasOwnProperty
方法会返回一个布尔值,指示对象自身属性中是否具有指定的属性
复制代码
var obj = new Object()
obj.animal = 'dog'
obj.hasOwnProperty('animal') // true
console.log(obj.hasOwnProperty('animal')) // Output: false
function changeObj() {
obj.people = obj.animal
delete obj.animal
}
changeObj()
obj.hasOwnProperty('animal') // false
obj.hasOwnProperty('people') // true
console.log(obj.hasOwnProperty('animal')) // Output: false
复制代码
总结:Object.keys、for...in、Object.getOwnPropertyNames() 三者类似
参考:MDN