如何仅使用传入的属性实例化JavaScript对象?
我正在尝试创建一个对象,该对象接受如下字段:如何仅使用传入的属性实例化JavaScript对象?,javascript,oop,Javascript,Oop,我正在尝试创建一个对象,该对象接受如下字段: var User = function(params) { if(params){ this.id = params.id; this.name = params.name; .. } } 如果模型中某个字段的属性存在,则会对其进行设置 如果它与模型不匹配,则不会包含在模型中 如果属性不存在,则不会设置它 因此,如果您这样做: var data = { id: 123,
var User = function(params) {
if(params){
this.id = params.id;
this.name = params.name;
..
}
}
- 如果模型中某个字段的属性存在,则会对其进行设置
- 如果它与模型不匹配,则不会包含在模型中
- 如果属性不存在,则不会设置它
var data = {
id: 123,
foo: 'bar'
};
var user = new User(data);
JSON.stringify(user); // { id: 123 }
最简单的方法是什么?我只能考虑对每个属性执行一个条件。如何使用传递的属性扩展用户属性?这样,任何新的内容都将添加到用户中 除了有条件地添加它们之外,没有其他方法,但您可以简化它 由于JavaScript是一种动态类型化语言,并且它还强制执行duck类型,所以不要期望像类这样的东西能够自动神奇地阻止添加意外属性 有关可能的简化,请参见以下代码段
函数BaseObject(){}
BaseObject.prototype={
defineRequiredProperties:函数(requiredProperties,propertyMap){
if(!(数组的requiredProperties实例)){
抛出错误(“'requiredProperties`参数必须是数组!”);
}
if(属性映射的类型==“对象”){
var=这个;
Object.keys(propertyMap).forEach(函数(propertyName){
//最好这样做,因为你可以检查
//属性存在,即使它是在原型链中定义的
if(requiredProperties.indexOf(propertyName)>-1){
[propertyName]=propertyMap[propertyName];
}
});
}
}
};
//根据OP的请求,这将防止迭代此自定义函数。
//它仍然可以调用,但不能枚举
Object.defineProperty(BaseObject.prototype,“defineRequiredProperties”{
可枚举:false
});
函数用户(参数){
此.defineRequiredProperties([“id”,“name”],参数);
}
//这是有效地派生BaseObject(实际上,链接
//BaseObject原型)以共享defineRequiredProperties
//跨越所有定制原型,保持干燥(不要重复)
User.prototype=Object.create(BaseObject.prototype);
var user=新用户({
id:11,
姓名:“Matías”,
姓氏:“菲德雷泽”
});
document.getElementById(“结果”).textContent=JSON.stringify(用户)代码>
函数(参数){
变量属性=['id','name',…];
对于(var i=0,length=properties.length;i
诚恳地说,您不需要条件。你的尝试很好。只需执行以下代码:
function User(params, hiddenNew) {
if (params) {
//if a property of a field in the model, it sets them
//if it does not match the model it does not get included in the model
this.id = params.id;
this.name = params.name;
}
//you can have additional functions here, or add it to its prototype
this.logMe = function() {
console.log(this);
};
//if the property is not there it does not set it
for (key in this) {
if (this[key] == undefined) {
delete this[key];
}
}
return this;
}
var data = {
id: 123,
foo: 'bar'
};
var user = new User(data);
user.logMe(); // testing function
而用户
对象正是您想要的:
User{id:123}
我没有使用jquery,但这不会导致结果:{id:123,foo'bar',name:null}
这与我想要的相反。你的尝试有什么问题?我觉得很好。使用extend()function@falsarella问题在于未定义的属性。下面的答案是返回自身的解析字符串化版本。这不符合@Tom所说的“如果属性不在那里,它就不设置它”的要求——它将属性设置为null
(例如,删除name:“Matías”
,然后运行它)。如果对象如下所示:this.id=null;this.name=null;this.anotherField=null
您得到{“id”:11,“name”:“Matías”,“anotherField”:null}
@PixMach现在它通过了要求;)我已经更新了code@PixMach很抱歉不存在的属性未定义,obviously@PixMach读我最后的评论。我相信你错了,或者给我看一段代码片段,在那里你可以证明你的陈述(例如在jsFiddle.net中)?投票人能解释原因吗?+1来自我。由于undefined
的行为保持原样,这就通过了OP给出的几个条件。在对象中仍然存在差异,可能扮演或不扮演任何角色,但在很大程度上,属性是实际未定义的还是仅未定义的
,这实际上是最好的方法。一个调整是执行返回JSON.parse(JSON.stringify(this))模型中的代码>。这会自动删除未定义的。谢谢@deceze我不想要未定义的,因为我用它来自动构建查询,所以查询会失败。结果证明这并不像我想象的那么好,它去掉了方法,所以在我实例化它之后,我不能再使用User来运行它的方法。我们得想出一个新的模式。结果只是添加了一个新方法User.prototype.model=function(data){return JSON.parse(JSON.stringify(new User(data));}代码>看起来很傻,但很有效。
function User(params, hiddenNew) {
if (params) {
//if a property of a field in the model, it sets them
//if it does not match the model it does not get included in the model
this.id = params.id;
this.name = params.name;
}
//you can have additional functions here, or add it to its prototype
this.logMe = function() {
console.log(this);
};
//if the property is not there it does not set it
for (key in this) {
if (this[key] == undefined) {
delete this[key];
}
}
return this;
}
var data = {
id: 123,
foo: 'bar'
};
var user = new User(data);
user.logMe(); // testing function