除了for/in循环之外,ECMAScript 5定义了两个用以枚举属性名称的函数。第一个是Object.keys(), 它返回一个数组,这个数组由对象中可枚举的自有属性的名称组成。
语法:
Object.keys(obj)
参数
obj
要返回其枚举自身属性的对象。
返回值
一个表示给定对象的所有可枚举属性的字符串数组。
描述
Object.keys 返回一个所有元素为字符串的数组,其元素来自于从给定的object上面可直接枚举的属性。这些属性的顺序与手动遍历该对象属性时的一致。
例子:
1 2 3 4 5 6 7 8 9 10 11
| var arr = ['a', 'b', 'c']; console.log(Object.keys(arr));
var obj = { 0: 'a', 1: 'b', 2: 'c' }; console.log(Object.keys(obj));
var anObj = { 100: 'a', 2: 'b', 7: 'c' }; console.log(Object.keys(anObj));
|
要在原生不支持的旧环境中添加兼容的Object.keys,请复制以下代码段
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| 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 对象下的对象时,不可枚举的属性也会获取到。
ECMAScript 5中第二E个枚举属性的函数是Object.getOwnPropertyNames(),它和Ojbect.keys()似,只是它返回对象的所有自有属性的名称,而不仅仅是可枚举的属性。在ECMAScript 3中是无法实现的类似的函数的,因为ECMAScript 3中没有提供任何方法来获取对象不可枚举的属性。
Object.getOwnPropertyNames()方法返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性但不包括Symbol值作为名称的属性)组成的数组。
语法
Object.getOwnPropertyNames(obj)
参数
obj
一个对象,其自身的可枚举和不可枚举属性的名称被返回。
返回值
在给定对象上找到的自身属性对应的字符串数组。
描述
Object.getOwnPropertyNames() 返回一个数组,该数组对元素是 obj自身拥有的枚举或不可枚举属性名称字符串。
数组中枚举属性的顺序与通过 for…in 循环(或 Object.keys)迭代该对象属性时一致。数组中不可枚举属性的顺序未定义。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| var arr = ["a", "b", "c"]; console.log(Object.getOwnPropertyNames(arr).sort());
var obj = { 0: "a", 1: "b", 2: "c"}; console.log(Object.getOwnPropertyNames(obj).sort());
Object.getOwnPropertyNames(obj).forEach(function(val, idx, array) { console.log(val + " -> " + obj[val]); });
|
如果你只要获取到可枚举属性,查看Object.keys或用for…in循环(还会获取到原型链上的可枚举属性,不过可以使用hasOwnProperty()方法过滤掉)。getOwnPropertyNames()并不会获取到原型链上的属性。
如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| function ParentClass() {} ParentClass.prototype.inheritedMethod = function() {};
function ChildClass() { this.prop = 5; this.method = function() {}; }
ChildClass.prototype = new ParentClass; ChildClass.prototype.prototypeMethod = function() {};
console.log( Object.getOwnPropertyNames( new ChildClass() ) );
|
愿你的坚持终有收获。
JavaScript中keys()和getOwnPropertyNames()详解。