Javascript JS不可枚举函数

Javascript JS不可枚举函数,javascript,backbone.js,Javascript,Backbone.js,我试图在原型对象上定义一个不可枚举的toJSON函数,但运气不好。我希望有类似于ECMAScript 5toJSON的东西: Object.defineProperty(obj, prop, { enumerable: false }); 但是,这将其定义为无法作为方法访问的属性。 [编辑:Nick错了;它可以作为一种方法访问。他的错误出现在代码中,而该问题中没有显示-有关详细信息,请参阅他对以下答案的评论。] 我希望能够以不可枚举的方式定义函数,因为我计划在所有基元类型的原型中定义(Stri

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

Object.defineProperty(obj, prop, { enumerable: false });
但是,这将其定义为无法作为方法访问的属性。
[编辑:Nick错了;它可以作为一种方法访问。他的错误出现在代码中,而该问题中没有显示-有关详细信息,请参阅他对以下答案的评论。]

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

这里的最终目标是能够使用嵌套集合递归地对主干模型/集合进行JSONify

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

  • 是否可以在原型上定义不可枚举的函数?如果是,怎么做
  • 有没有更好的方法来jsonifnestedbackbone模型

  • 我不明白,为什么你不能把它作为一种方法

    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 */);
    
    甚至直接在

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

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

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

    您可以看到。

    Paul S.关于需要设置属性定义的
    值而不是
    get
    ,这是正确的,但我想补充的是,您不需要传递
    枚举:false
    ,因为false是
    对象中该选项的默认值。defineProperty()
    答案可以简化为:

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

    在对象中循环时,始终可以避免对象中的可枚举函数属性。您可以创建一个函数,该函数将调用具有所需属性的任何对象,并设置一个条件以不在循环列表中获取该属性,而不是在每个对象中定义属性并将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
    

    根据定义,方法是对象的属性。你在画一个根本不存在的区别。如果您希望它是不可枚举的,那么显然您正在枚举对象的属性。是的,但是我希望它是不可枚举的属性,就像object.defineProperty是不可枚举的一样。ie,在对(obj中的x)使用
    时不会重复执行。同样,方法是引用函数的对象的属性。你拥有的代码是用来使属性不可枚举的。为了澄清@user2437417的观点:Nick的代码是正确的,所以他的问题有点混乱。当他说“然而,这将它定义为无法作为方法访问的属性”时,他错了;它可以作为一种方法访问。阅读下面他对答案的评论,发现他的真正问题在于他访问答案的方式不正确。如果他展示了他试图使用的代码行-这并没有达到他想要的效果-这将是显而易见的。太棒了,谢谢!问题是我使用的是
    get
    而不是
    value
    ,我无法将其作为函数访问。get调用函数时不传递任何参数,然后假装该属性等于函数的
    返回值,因此当您想执行
    SJON(args)时,您正在执行
    SJON()(args)
    好的。最后一个问题,如果你不介意的话;此方法是否会导致一些与使用可枚举函数扩展对象原型相同的问题?@NickMitchinson否,这只会将属性添加到
    foo
    用户对象中,而不是将属性添加到foo.prototype;)不可枚举的属性将显示为。还有,编辑。谢谢,我只在问题中明确说明了这一点,但值得注意的是,它实际上并不需要。为什么/什么时候会使用这种技术,而不是将新函数标记为不可枚举?为了高性能,我将不深入讨论,但在v8引擎中,算法说[所有然后一个]当您编写对象时,此算法用于全局错误对象。defineProperty(对象,“属性”=>算法将从此点开始工作,微型计算机将开始运行,以在递归堆栈中应用您拥有的所有对象和属性[all],然后将取用定义了[one]的对象和属性想象一下,如果你有一个大的对象,你正在杀死你的CPU,fn.call将工作[!一个然后所有]意味着如果你没有选择(这个),那么这将是所有(窗口对象)。
    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