【问题标题】:List Object's built-in Properties列出对象的内置属性
【发布时间】:2010-09-20 17:25:30
【问题描述】:

有没有办法让我遍历 Javascript 对象的内置属性?

for...in 让我接近我想去的地方,但是“for...in 循环不会迭代内置属性。”

【问题讨论】:

  • 能否将对象字符串化为 JSON 并解析结果?

标签: javascript reflection properties


【解决方案1】:

这将适用于 JSON。它没有经过太多测试:

<style>
.tree {
    margin-left:5px;
}
</style>
<div id='out'></div>
<script type="text/javascript">
data = {"feep":{"bar":{"baz":"37628","quux":{"a":"179","b":"7"}},"foo":"1025"},"Bleh":"1234"}
$('out').innerHTML = renderJSON(data)

function renderJSON(obj) {
    var keys = []
    var retValue = ""
    for (var key in obj) {
       //$('out').innerHTML = $('out').innerHTML +"<br />" + key + ", " + obj[key]      
        if(typeof obj[key] == 'object') {
            retValue += "<div class='tree'>" + key                      
            retValue += renderJSON(obj[key])
            retValue += "</div>"
        }
        else {
            retValue += "<div class='tree'>" + key + " = " + obj[key] + "</div>"
        }

       keys.push(key)
    }
    return retValue

}
</script>

【讨论】:

    【解决方案2】:

    当您说“内置属性”时,您具体指的是哪一组属性?

    来自 Douglas Crockford 的 'JavaScript - The Good Parts'

    for in 语句可以遍历所有 对象中的属性名称。 枚举将包括所有 属性——包括函数和 原型属性,你可能 不感兴趣——原来如此 有必要过滤掉你的值 不想要。最常见的过滤器 是 hasOwnProperty 方法和 使用 typeof 排除函数:

    var name; 
    for (name in another_stooge) 
    {
        if (typeof another_stooge[name] !== 'function') {
            document.writeln(name + ': ' + another_stooge[name]);
        } 
    }
    

    【讨论】:

    • 我的特定用例是枚举 Array.prototype 的内置方法。来自 MDC 核心 javascript 参考:“for...in 循环不会迭代内置属性。” Array.prototype 上的简单循环证实了这一点。
    【解决方案3】:

    答案是否定的。您不能枚举不可枚举的属性。然而,至少有两种方法可以解决这个问题。

    首先是生成所有可能的字符组合以用作测试属性名称(想想:a、b、c、... aa、ab、ac、ad、...)。鉴于标准社区以提出非常长的方法名称(getElementsByTagNames、propertyIsEnumerable)而闻名,这种方法需要一些耐心。 :-)

    另一种方法是从一些预定义列表中测试已知的原生属性。

    例如:对于array,您将测试Function.prototype 的所有已知本机属性:

    prototype caller constructor length name apply call toSource toString valueOf toLocaleString
    

    ...以及从Object.prototype继承的东西:

    __defineGetter__ __defineSetter__ hasOwnProperty isPrototypeOf __lookupGetter__
    __lookupSetter__ __noSuchMethod__ propertyIsEnumerable unwatch watch
    

    ...以及从Array继承的东西:

    index input pop push reverse shift sort splice unshift concat join slice indexOf lastIndexOf 
    filter forEach every map some reduce reduceRight
    

    ..最后,可选地,您正在测试的对象的每个可枚举属性:

    for (var property in myArrayObject) myPossibleProperties.push( property );
    

    然后,您将能够测试其中的每一个,以查看它们是否存在于对象实例中。

    这不会显示未知的不可枚举成员(未记录或由其他脚本设置),但允许您列出可用的原生属性。

    我在Mozilla Developer CenterMSDN 上找到了有关原生Array 属性的信息。

    【讨论】:

      【解决方案4】:

      不,您不能列出对象的内置属性。 但是你可以参考实施者的参考。 例如,要了解在 Firefox 上实现的 Math 对象的所有方法和属性,您将使用 Firefox 的 Javascript 数学参考:https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Math

      【讨论】:

        【解决方案5】:

        我意识到这个问题已经存在三年了,但是现在,有了 ES5,它是可能的:

        &gt;&gt;&gt; Object.getOwnPropertyNames(Object)

        ["prototype", "getPrototypeOf", "getOwnPropertyDescriptor", "keys", "defineProperty", "defineProperties", "create", "getOwnPropertyNames", "isExtensible", "preventExtensions", "freeze", "isFrozen", "seal", "isSealed", "length", "arity", "name", "arguments", "caller"]

        【讨论】:

        • 澄清一点,Object.getOwnPropertyNames(Array) 提供了 Array 的内置属性。
        猜你喜欢
        • 2018-10-03
        • 2011-02-10
        • 1970-01-01
        • 1970-01-01
        • 2015-02-12
        • 2010-09-17
        • 2018-02-07
        • 1970-01-01
        相关资源
        最近更新 更多