如何链接两个 JavaScript 对象?

Posted

技术标签:

【中文标题】如何链接两个 JavaScript 对象?【英文标题】:How can I link two JavaScript objects? 【发布时间】: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) 的对象。 【参考方案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

【讨论】:

以上是关于如何链接两个 JavaScript 对象?的主要内容,如果未能解决你的问题,请参考以下文章

如何理解Javascript中类和对象这两个概念

如何在javascript中返回两个对象值[重复]

javascript合并两个json对象

JavaScrip和Java一样吗?

javascript中对两个对象进行排序 和 java中的两个对象排序

如何在Javascript中链接两个拼接方法?