假设我这样创建一个对象:

var myObject =
        {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};

检索属性名列表的最佳方法是什么?例如,我想以一些变量“键”结束,这样:

keys == ["ircEvent", "method", "regex"]

当前回答

这可以在大多数浏览器中工作,甚至在IE8中,并且不需要任何类型的库。Var I是你的钥匙。

var myJSONObject =  {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"}; 
var keys=[];
for (var i in myJSONObject ) { keys.push(i); }
alert(keys);

其他回答

以公认的答案为基础。

如果对象有你想要调用的属性,那么说.properties()试试!

var keys = Object.keys(myJSONObject);

for (var j=0; j < keys.length; j++) {
  Object[keys[j]].properties();
}

Mozilla有完整的实现细节,关于如何在不支持它的浏览器中实现它,如果这有帮助的话:

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;
    };
  })();
}

你可以把它包括在你喜欢的任何地方,但可能是在脚本堆栈顶部的某种extensions.js文件中。

正如Sam Dutton回答的那样,ECMAScript第5版引入了一种新的方法。Object.keys()将做你想做的事情,并在Firefox 4, Chrome 6, Safari 5和IE 9中得到支持。

您也可以很容易地在不支持该方法的浏览器中实现该方法。然而,有些实现并不完全与Internet Explorer兼容。这里有一个更兼容的解决方案:

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 (o) {
        if (typeof o != "object" && typeof o != "function" || o === null)
            throw new TypeError("Object.keys called on a non-object");
    
        var result = [];
        for (var name in o) {
            if (hasOwnProperty.call(o, name))
                result.push(name);
        }
    
        if (hasDontEnumBug) {
            for (var i = 0; i < DontEnumsLength; i++) {
                if (hasOwnProperty.call(o, DontEnums[i]))
                    result.push(DontEnums[i]);
            }   
        }
    
        return result;
    };
})();

请注意,当前接受的答案不包括检查hasOwnProperty(),并将返回通过原型链继承的属性。它也没有解释Internet Explorer中著名的DontEnum错误,即原型链上的不可枚举属性会导致本地声明的具有相同名称的属性继承其DontEnum属性。

实现Object.keys()将为您提供更健壮的解决方案。

编辑:在最近与Prototype的知名贡献者kangax讨论之后,我基于他Object.forIn()函数的代码实现了DontEnum错误的解决方案。

这可以在大多数浏览器中工作,甚至在IE8中,并且不需要任何类型的库。Var I是你的钥匙。

var myJSONObject =  {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"}; 
var keys=[];
for (var i in myJSONObject ) { keys.push(i); }
alert(keys);

因为我几乎在每个项目中都使用了underscore.js,所以我会使用keys函数:

var obj = {name: 'gach', hello: 'world'};
console.log(_.keys(obj));

它的输出将是:

['name', 'hello']