【发布时间】:2021-01-15 14:17:12
【问题描述】:
我想创建一个返回对象所有属性的函数:
这是我的初始代码:
function dir(obj) {
if (obj === null || obj === Object.prototype) {
return [];
}
var names = Object.getOwnPropertyNames(obj);
return names.concat(dir(Object.getPrototypeOf(obj)));
}
我有 ES6 类,我想在其中隐藏一些属性:
class Lexer {
constructor(input, { whitespace = false } = {}) {
this.__input__ = input.replace(/\r/g, '');
var internals = {};
[
'_i', '_whitespace', '_col', '_newline', '_line',
'_state', '_next', '_token', '_prev_char'
].forEach(name => {
Object.defineProperty(this, name, {
configurable: false,
enumerable: false,
get() {
return internals[name];
},
set(value) {
internals[name] = value;
}
});
});
this._whitespace = whitespace;
this._i = this._line = this._col = this._newline = 0;
this._state = this._next = this._token = null;
this._prev_char = '';
}
token() {
}
...
}
我遇到的问题是 Object.getOwnPropertyNames 返回可枚举属性,而 Object.key 不返回 ES6 类方法。所以我如果使用第一个函数,我会得到隐藏的道具,如果我使用第二个函数,我只会得到__input__。
有没有办法检测某些东西是否是隐藏属性而不是 ES6 类方法?我不想检测某个东西是否是函数,因为我想要更通用的东西,因为不能有作为函数的可枚举属性。
我还发现,对于 ES5 构造函数,有一个构造函数属性也是不可枚举的,其行为类似于 ES6 方法(在我的 Lexer 类的情况下,它使用相同的标记方法)。
注意:这不是 Y/X 问题我想为我的 Scheme 解释器创建 dir 函数,它可以像 Python 中的类似函数一样工作,它应该与 ES5 函数构造函数对象和 ES6 类对象一起工作。
我试过这个:
function dir(obj, proto) {
if (obj === null || obj === Object.prototype) {
return [];
}
var names = Object.getOwnPropertyNames(obj);
if (!proto) {
names = names.filter(name => {
var d = Object.getOwnPropertyDescriptor(obj, name);
return d.configurable && d.enumerable;
});
}
return names.concat(dir(Object.getPrototypeOf(obj), true));
}
但我不知道这是否是最好的方法,因为用户可能想要创建原型的属性描述符(我不确定这是否可能发生)。我想要 100% 的工作解决方案而不是解决方法。你知道有什么方法可以让它工作吗?
编辑:
即使我有适合我的情况的有效解决方案,我想知道 ES6 属性实际上是否与不可枚举的属性无法区分。
特别是如果您可以检测到 foo 是否与 bar 不同:
class Test {
constructor() {
Object.defineProperty(this, 'foo', {
enumerable: false,
configurable: false,
value: function() { alert('foo') }
});
}
bar() {
alert('bar');
}
}
唯一的区别是 bar 在原型对象上,没有其他方法可以检测到区别吗?
【问题讨论】:
-
@Teemu 是的,我已经用我尝试过的方法编辑了问题,但我不确定这是否是最好的方法。
-
@Teemu 这不起作用,任何提示如何使用它?所有方法都有描述符,说明该方法不可枚举。因此,据我所知,无法区分方法和隐藏属性描述符。
-
我的错,我没有意识到
getOwnPropertyNames也返回了不可枚举的属性,使用基本上与您在示例中已有的相同,只是迭代一个对象而不是一个数组。 -
@Teemu 您的解决方案可能会更快,因为它一次返回所有描述符。
-
Scheme 中的对象模型是什么?方案代码甚至会知道原型继承吗?