在JavaScript对象中添加属性

7

我知道这可能是一个重复的问题,但我发现很多类似于我的问题,但它们的答案并没有回答我的问题。例如,这个页面https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty,据我所知,也没有包含我的问题的答案。

请注意,Object.defineProperty()方法是用于在对象上定义新属性或修改现有属性的方法。如果您需要了解如何使用此方法,请参考MDN文档中的示例和详细说明。

This is what I have:

var User = function() {
  this.name = '';
}

User.prototype.password = '';
// or
Object.defineProperty(User.prototype, 'password', {enumerable: true, configurable: true, writable: true});

console.log(new User()); // User {name: ""}

This of course adds password to the prototype of the object, but I'd like to add the password as a member after the constructor has been defined. Is there a way to achieve this?

var User = function() {
  this.name = '';
}

User.prototype.password = '';

console.log(new User()); // User {name: "", password: ""}


4
不要将成员数据放在原型上。如果这样做,该类型的所有实例将具有相同的成员值。 - bhspencer
所以你的问题是如何使原型属性出现在控制台日志中?顺便说一下,应该是 defineProperty(User.prototype, ...。无论如何,我不明白你试图通过将 password 放在原型上来实现什么目的。难道它不需要像 name 一样成为每个用户都不同的实例属性吗? - user663031
我认为问题出在这里:他想要在已经定义构造函数之后给User函数添加更多的实例属性。这就是我在我的答案中试图解决的问题。 - nils
当然,@nils。抱歉之前没有说清楚。控制台日志并不是问题的一部分。我已经更新了答案以便更加清晰明了。 - Philipp Gfeller
1个回答

4
如果你想使用 new 运算符创建一个新的对象,但无法修改构造函数,那么这可能会变得困难。据我所知,如果你正在使用 new 运算符,那么构造函数是唯一可以定义实例变量的地方。
如果你使用 Object.create 创建对象,你可以在第二个参数中传递进一些其他属性,这类似于 Object.defineProperty。请参考此处
var User = function() {
  this.name = '';
}

User.prototype.xyz = ''; // Add whatever you need to your prototype

var o = Object.create(User.prototype, {
    'password': {enumerable: true, configurable: true, writable: true, value: ''}
});
User.call(o);

如果您需要在对象创建之前执行此操作,您可以始终在另一个函数中包装原始构造函数:

var User = function() {
  this.name = '';
}

User.prototype.xyz = ''; // Add whatever you need to your prototype

var originalUser = User;

var User = function() {
    this.password = '';
    originalUser.call(this);
}

User.prototype = originalUser.prototype;

var o = new User();

我个人认为使用Object.create版本更加清晰和不容易出错(特别是当你想要在不同的时间添加多个属性时)。


这很令人困惑。你定义了一个构造函数,但是没有使用它来创建对象,而是使用Object.create,然后将构造函数作为常规函数调用以充当一种初始化程序?然后在第二个示例中,你创建了一个版本的User,然后用另一个版本覆盖它,然后从一个版本复制原型到另一个版本——我完全不理解。 - user663031
我做了一些假设:1. 他可能也想在其他操作中使用构造函数。 2. 他想要在使用new创建的对象中添加更多实例属性,而不是在构造函数中定义。他不希望它们出现在原型中,否则他的值将被所有实例覆盖 - 所以我想尽可能贴近他的代码。这样是否更有意义?当然,我很乐意听取改进建议。 - nils
虽然这两种解决方案都可以工作,但我还没有决定要使用哪一种。不过还是谢谢! - Philipp Gfeller

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接