最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - JS non-enumerable function - Stack Overflow

programmeradmin1浏览0评论

I'm trying to define a non-enumerable toJSON function on a prototype object without much luck. I'm hoping for something similar to ECMAScript 5 toJSON:

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

However this defines it as a property which cannot be accessed as a method.
[EDIT: Nick is wrong; it can be accessed as a method. His mistake was in code that is not shown in this question - see his comments on answers below, for details.]

I was hoping to be able to define the function in a non-enumerable fashion, as I was planning to define in the prototypes of all primitive types (String, Number, Boolean, Array, and Object), so that I can recursively apply the function through complex objects.

The end goal here is to be able JSONify a Backbone model/collection with nested collections recursively.

I guess in total I have two main questions:

  1. Is it possible to define a non-enumerable function on a prototype? If so how?
  2. Is there a better way to JSONify nested Backbone models?

I'm trying to define a non-enumerable toJSON function on a prototype object without much luck. I'm hoping for something similar to ECMAScript 5 toJSON:

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

However this defines it as a property which cannot be accessed as a method.
[EDIT: Nick is wrong; it can be accessed as a method. His mistake was in code that is not shown in this question - see his comments on answers below, for details.]

I was hoping to be able to define the function in a non-enumerable fashion, as I was planning to define in the prototypes of all primitive types (String, Number, Boolean, Array, and Object), so that I can recursively apply the function through complex objects.

The end goal here is to be able JSONify a Backbone model/collection with nested collections recursively.

I guess in total I have two main questions:

  1. Is it possible to define a non-enumerable function on a prototype? If so how?
  2. Is there a better way to JSONify nested Backbone models?
Share Improve this question edited Oct 4, 2019 at 11:19 ToolmakerSteve 21.2k16 gold badges109 silver badges221 bronze badges asked Jul 3, 2013 at 2:04 Nick MitchinsonNick Mitchinson 5,4801 gold badge27 silver badges31 bronze badges 4
  • A method by definition is a property of an object. You're drawing a distinction that doesn't exist. If you want it to be non-enumerable, then obviously you're enumerating properties of an object. – user2437417 Commented Jul 3, 2013 at 2:10
  • 1 Yes, however I would like it to be a non-enumerable property, in the same way that Object.defineProperty is non-enumerable. ie, is not iterated through when using for (x in obj) – Nick Mitchinson Commented Jul 3, 2013 at 2:15
  • 1 Right. Again, a method is a property of an object that references a function. The code that you have is what you'd use to make the property non-enumerable. – user2437417 Commented Jul 3, 2013 at 2:16
  • To clarify @user2437417's point: Nick's code is correct - so his question is a bit confused/confusing. When he says "However this defines it as a property which cannot be accessed as a method." - he is wrong; it can be accessed as a method. Reading his comment's on answers below, it turns out his real problem was that the way he accessed it was incorrect. If he had shown the line of code were he tried to use it - that didn't do what he wanted - this would have been immediately apparent. – ToolmakerSteve Commented Oct 4, 2019 at 11:16
Add a comment  | 

3 Answers 3

Reset to default 16

I don't get it, why can't you access it as a method?

var foo = {};

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

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

If you wanted it on the prototype, it's as easy as

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

or even directly in Object.create

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

However, unless you're creating instances of foo, it won't show up if you try to foo.bar, and only be visible as foo.prototype.bar.

If foo has it's own prototype (e.g. foo = Object.create({})), you can get it with Object.getPrototypeOf, add the property to that and then foo.bar would work even if it is not an instance.

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

You can see visibility of enumerable vs non-enumerable properties here.

Paul S. is right about needing to set the property definition's value instead of a get, but I wanted to add that you don't need to pass enumerable: false, because false is the default for that option in Object.defineProperty() The answer can be simplified to:

var foo = {};    

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

foo.bar();

Always you can avoid enumerable functions properties in object when you looping through it. And instead of define property in each object and set enumerable to false , you can create function which will call to any object with the property you want and put a condition to not take the property in the looping list. here is the example :

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
发布评论

评论列表(0)

  1. 暂无评论