JS不可枚举函数

JS non-enumerable function

本文关键字:函数 不可枚举 JS      更新时间:2023-09-26

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

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

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

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

这里的最终目标是能够递归地JSONify具有嵌套集合的主干模型/集合。

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

  1. 有可能在原型上定义一个不可枚举的函数吗?如果是,怎么办
  2. 有没有更好的方法来实现JSONify嵌套的主干模型

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

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 */);

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

Paul S.关于需要设置属性定义的value而不是get是正确的,但我想补充一点,您不需要通过enumerable: false,因为在Object.defineProperty()中该选项的默认值为false。答案可以简化为:
var foo = {};    
Object.defineProperty(foo, 'bar', {
    value: function(){ console.log('calling bar!'); }
});
foo.bar();

当你循环遍历对象时,你总是可以避免在对象中使用可枚举函数属性。你可以创建一个函数,它将调用任何具有你想要的属性的对象,并设置一个不在循环列表中使用该属性的条件,而不是在每个对象中定义属性并将可枚举设置为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