如何支持在我的 class - javascript / nodejs 的实例上调用 Object.entries?
How can support Object.entries being called on an instance of my class - javascript / nodejs?
我试图让我的 class 表现得像一个“普通”对象,因为当它在 object.entries
中被调用时,它 returns 是一个键值对数组。经过大量搜索后,我已经能够使我的 class 可迭代。但是我找不到从哪里开始实施 object.entries
.
这里是我的目的地,
'use strict'
class Person {
#name
constructor(name) {
this.#name = name
}
get name () {
return this.#name
}
*iterator () {
var props = Object.getOwnPropertyNames(Object.getPrototypeOf(this))
for (const prop of props) {
if (typeof this[prop] !== 'function') {
const o = {}
o[prop] = this[prop]
yield o
}
}
}
[Symbol.iterator] () {
return this.iterator()
}
}
const person = new Person ('bill')
//works - produces { name: 'bill' }
for (const prop of person){
console.log (prop)
}
// doesn't work. Prints an empty array
console.log (Object.entries(person))
实际上您不必实现迭代器。 Object.entries
不起作用的原因是由于 #
属性 被视为私有的,因此不会返回。如果您删除 #
name
将由 Object.entries
返回,如下例所示。
class Person {
name
constructor(name) {
this.name = name
}
}
const person = new Person ('bill')
// doesn't work. Prints an empty array
console.log(Object.entries(person))
问题是您的实例没有 public“自己的”(不是继承的)属性,Object.entries
包含在其数组中。
I am trying to get my class to behave like a "normal" object, in that when it is called in object.entries it returns an array of key value pairs.
这是默认行为,无论您是通过 class 构造函数还是其他方式创建对象。
After quite a bit of searching around I have been able to make my class iterable.
Object.entries
与对象是否可迭代无关。
我认为如果不将 name
设为“自己的”数据 属性,就无法制作 Object.entries
return [[name, "value"]]
。但是您可以通过 Object.defineProperty
:
将其设为只读自己的数据 属性
class Person {
#name;
constructor(name) {
this.#name = name;
Object.defineProperty(this, "name", {
value: name,
writable: false,
enumerable: true,
configurable: true
});
}
}
const bill = new Person("Bill");
console.log(`bill.name:`, bill.name);
console.log(`Object.entries(bill):`, Object.entries(bill));
我一直 #name
在那里,但可能没有理由这样做,所以:
class Person {
constructor(name) {
Object.defineProperty(this, "name", {
value: name,
writable: false,
enumerable: true,
configurable: true
});
}
}
const bill = new Person("Bill");
console.log(`bill.name:`, bill.name);
console.log(`Object.entries(bill):`, Object.entries(bill));
如果你希望能够在内部设置 name
,只需给自己一个重复 defineProperty
:
的私有方法
class Person {
constructor(name) {
this.#setName(name);
}
#setName(name) {
Object.defineProperty(this, "name", {
value: name,
writable: false,
enumerable: true,
configurable: true
});
}
}
const bill = new Person("Bill");
console.log(`bill.name:`, bill.name);
console.log(`Object.entries(bill):`, Object.entries(bill));
不幸的是,因为 属性 是可配置的,所以您的代码不是唯一可以使用 defineProperty
来更改它的代码。 (这很像函数上的 name
属性,默认情况下它是只读的,但可以通过 defineProperty
更改。)所以它与 [=19= 不完全相同] 和 get name
,它只是在为 Object.entries
.
提供支持时关闭
我试图让我的 class 表现得像一个“普通”对象,因为当它在 object.entries
中被调用时,它 returns 是一个键值对数组。经过大量搜索后,我已经能够使我的 class 可迭代。但是我找不到从哪里开始实施 object.entries
.
这里是我的目的地,
'use strict'
class Person {
#name
constructor(name) {
this.#name = name
}
get name () {
return this.#name
}
*iterator () {
var props = Object.getOwnPropertyNames(Object.getPrototypeOf(this))
for (const prop of props) {
if (typeof this[prop] !== 'function') {
const o = {}
o[prop] = this[prop]
yield o
}
}
}
[Symbol.iterator] () {
return this.iterator()
}
}
const person = new Person ('bill')
//works - produces { name: 'bill' }
for (const prop of person){
console.log (prop)
}
// doesn't work. Prints an empty array
console.log (Object.entries(person))
实际上您不必实现迭代器。 Object.entries
不起作用的原因是由于 #
属性 被视为私有的,因此不会返回。如果您删除 #
name
将由 Object.entries
返回,如下例所示。
class Person {
name
constructor(name) {
this.name = name
}
}
const person = new Person ('bill')
// doesn't work. Prints an empty array
console.log(Object.entries(person))
问题是您的实例没有 public“自己的”(不是继承的)属性,Object.entries
包含在其数组中。
I am trying to get my class to behave like a "normal" object, in that when it is called in object.entries it returns an array of key value pairs.
这是默认行为,无论您是通过 class 构造函数还是其他方式创建对象。
After quite a bit of searching around I have been able to make my class iterable.
Object.entries
与对象是否可迭代无关。
我认为如果不将 name
设为“自己的”数据 属性,就无法制作 Object.entries
return [[name, "value"]]
。但是您可以通过 Object.defineProperty
:
class Person {
#name;
constructor(name) {
this.#name = name;
Object.defineProperty(this, "name", {
value: name,
writable: false,
enumerable: true,
configurable: true
});
}
}
const bill = new Person("Bill");
console.log(`bill.name:`, bill.name);
console.log(`Object.entries(bill):`, Object.entries(bill));
我一直 #name
在那里,但可能没有理由这样做,所以:
class Person {
constructor(name) {
Object.defineProperty(this, "name", {
value: name,
writable: false,
enumerable: true,
configurable: true
});
}
}
const bill = new Person("Bill");
console.log(`bill.name:`, bill.name);
console.log(`Object.entries(bill):`, Object.entries(bill));
如果你希望能够在内部设置 name
,只需给自己一个重复 defineProperty
:
class Person {
constructor(name) {
this.#setName(name);
}
#setName(name) {
Object.defineProperty(this, "name", {
value: name,
writable: false,
enumerable: true,
configurable: true
});
}
}
const bill = new Person("Bill");
console.log(`bill.name:`, bill.name);
console.log(`Object.entries(bill):`, Object.entries(bill));
不幸的是,因为 属性 是可配置的,所以您的代码不是唯一可以使用 defineProperty
来更改它的代码。 (这很像函数上的 name
属性,默认情况下它是只读的,但可以通过 defineProperty
更改。)所以它与 [=19= 不完全相同] 和 get name
,它只是在为 Object.entries
.