【问题标题】:How can I link two JavaScript objects?如何链接两个 JavaScript 对象?
【发布时间】:2017-09-28 04:31:36
【问题描述】:

假设我有一个对象 (obj1),其中 obj1 中的一个值是另一个对象 (obj2)。有什么办法可以让检查 obj1 中的任何内容(例如 obj1.username)也会自动检查 obj2(obj1.ob2.username)?

这种情况的用例是如果 obj1 中不存在某些东西,我还想在 obj2 返回 null 之前检查它。

示例用法:

var user = {username: "David"} // obj2
var member = {nickname: "Dave", user: user} // obj1

console.log(user.username) // "David"
console.log(user.nickname) // null

console.log(member.username) // "David"
console.log(member.nickname) // "Dave"

这是在 Node.js 中使用的。

--编辑--

我忘记指出成员和用户是从我用来与名为 Discord 的应用程序交互的库中的类创建的。

发送消息时,会触发一个事件,我会收到成员对象之类的信息(其中包含指向用户对象的链接)。

Here is the structure of a user.

Here is the structure of a member.

Object.defineProperty(Discord.Member.prototype, 'username', {
    get: function() { return this.user.username; },
    set: function(newValue) { this.user.username = newValue; }
});

上述方法按预期工作,但仅适用于username 属性。我考虑将这个应用于用户的每个属性,但是当我尝试遍历创建的用户的属性时,一些(如.createdAt)没有出现在列表中。

我知道我可以手动完成并手动编写每个 defineProperty,但这里的想法是用户将随着时间的推移不断更新新属性,所以我希望它执行我上面描述的操作。

【问题讨论】:

  • 如果成员是用户,它似乎是原型继承的一个不错的用例(或者“类”,如果你这样做的话)。
  • 写 user.prototype = member
  • {get nickname() { return this.user.username }, user}?
  • @binariedMe 号
  • 我将它用于 Discord 机器人应用程序,因此成员和用户都是通过诸如“已发送消息”之类的事件提供给我 (discord.js.org/#/docs/main/stable/class/GuildMember) 的对象。

标签: javascript node.js object indexing reference


【解决方案1】:

您可以使用Proxy 和内部使用getter 先检查属性是否存在于原始对象中,然后再检查其他对象中。

var user = {
  username: "David"
} // obj2

var member = {
  nickname: "Dave",
  user: user,
} // obj1


var pMember = new Proxy(member, {
  get: function(target, prop) {
    if (target[prop]) return target[prop];
    else if (target.user[prop]) return target.user[prop];
  }
});

console.log(pMember.nickname)
console.log(pMember.username)

【讨论】:

  • 我不能为“成员”创建一个新变量,它必须是已经存在的成员。
  • 成员来自库的类,所以我需要更改从类创建的成员对象。 Object.defineProperty(Discord.Member.prototype, 'username', { get: function() { return this.user.username; }, set: function(newValue) { this.user.username = newValue; } }); 这适用于用户名属性,但是我需要它适用于 github.com/hydrabolt/discord.js/blob/stable/src/structures/… 的所有属性。如果我遍历用户,我可以重复 defineProperty 方法,但是其中的某些属性(如 createdAt)在我迭代时不会显示。
  • 警告。 getset 代理处理程序会显着影响已放置代理的对象的性能,在频繁访问的对象上使用代理时要小心。 .此外,代码答案示例有点危险,因为它没有明确检查属性是否存在,并且会为所有 target[prop] == false && target.user[prop] == false 的属性返回 undefined(注意不是 === false)
  • 这并不是说它不起作用,它是我最初描述的完美解决方案,它是为了我的使用,我在我的代码中获得了数百个地方的成员,所以我需要它是任何成员中的索引值也会自动检查 member.user,而无需我每次都替换成员,并且该成员仍然是首先给我的成员,用于将其传递回库中的函数,例如“ deleteLastMessages(member, number)".
  • 你能用原型扩展 guildMember 来获得类似jsfiddle.net/Lg0wyt9u/1861 的属性吗?
【解决方案2】:

使用继承:

var user = {username: "David"} // obj2
var member =Object.assign(Object.create(user),{nickname: "Dave", user: user}); // obj1

console.log(member.username);

http://jsbin.com/nojolizewu/edit?console

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-14
    • 2022-01-10
    • 1970-01-01
    相关资源
    最近更新 更多