8

我正在尝试toJSON在原型对象上定义一个不可枚举的函数,但运气不佳。我希望有类似于 ECMAScript 5 的东西toJSON

Object.defineProperty(obj, prop, { enumerable: false });

但是,这将其定义为不能作为方法访问的属性。
[编辑:尼克错了;它可以作为一种方法访问。他的错误在于此问题中未显示的代码 - 有关详细信息,请参阅他对下面答案的评论。]

我希望能够以不可枚举的方式定义函数,因为我计划在所有原始类型(、、、、和)的原型中定义,String这样我Number就可以通过复杂的对象递归地应用函数。BooleanArrayObject

这里的最终目标是能够递归地对带有嵌套集合的 Backbone 模型/集合进行 JSON 化。

我想我总共有两个主要问题:

  1. 是否可以在原型上定义不可枚举的函数?如果有怎么办?
  2. 有没有更好的方法来 JSONify 嵌套的 Backbone 模型?
4

3 回答 3

16

我不明白,为什么你不能将它作为一种方法访问?

var foo = {};

Object.defineProperty(foo, 'bar', {
    enumerable: false,
    value: function () {console.log('foo.bar\'d!');}
});

foo.bar(); // foo.bar'd!

如果你想要它在原型上,它就像

Object.defineProperty(foo.prototype, /* etc */);

甚至直接在Object.create

foo.prototype = Object.create(null, {
    'bar': {value: function () {/* ... */}}
});

但是,除非您正在创建 的实例,否则如果您尝试这样做,它将不会显示foo并且foo.bar只会显示为foo.prototype.bar.

如果foo有它自己的原型(例如foo = Object.create({})),您可以使用 获取它 Object.getPrototypeOf,将属性添加到其中,然后foo.bar即使它不是实例也可以工作。

var proto = Object.getPrototypeOf(foo); // get prototype
Object.defineProperty(proto, /* etc */);

您可以在此处查看可枚举与不可枚举属性的可见性

于 2013-07-03T02:13:06.187 回答
1

Paul S. 关于需要设置属性定义value而不是 a是正确的get,但我想补充一点,您不需要 pass enumerable: false,因为 false 是Object.defineProperty()答案中该选项的默认值可以简化为:

var foo = {};    

Object.defineProperty(foo, 'bar', {
    value: function(){ console.log('calling bar!'); }
});

foo.bar();
于 2013-07-03T02:23:51.883 回答
0

循环遍历对象时,始终可以避免对象中的可枚举函数属性。而不是在每个对象中定义属性并将 enumerable 设置为 false ,您可以创建函数,该函数将调用具有您想要的属性的任何对象,并设置一个条件以不将属性放入循环列表中。这是示例:

const obj = {
name: "myName",
title: "developer"
}


function prop() {
this.loop = function(i) {
    for (i in this) {
        if (typeof(this[i]) == "function") {
            continue;
        } else {
            console.log(this[i]);
        }
    }
}
}
prop.call(obj);
obj.loop(); 
output >>  myName, developer
于 2019-04-02T13:32:09.677 回答