Firstly, I would allow the object constructor to take a parameter
function User(params) {
...
To allow an arbitrary number of arguments to be supplied, the params parameter will accept an object literal:
new User({name: 'name 1', id: 1});
Next I pass the params object to a generic function that will handle assignment of properties from the params object to the target object.
function setObjectProperties(params, target) {
}
The setObjectProperties function needs to verify that we have been correctly passed some data. It checks if both params and target are defined:
function setObjectProperties(params, target) {
if (params !== undefined && target !== undefined) {
}
}
Once we're confident that we have something to work with, it is time to iterate over the parameters and assign to the object properties.
function setObjectProperties(params, target) {
if (params !== undefined && target !== undefined) {
$.each(params, function (i, property) {
this[i] = property;
}, target);
}
}
Using jQuery's $.each function, which iterates over an objects properties without the side effect of iterating over all object properties such as prototypes, etc. This works but mean we need to deal with the side-effect that this gets redefined inside the callback closure of the $.each function. We now no longer know what are original object was.
However, jQuery's $.proxy function is designed to allow us to call a function whilst designating what we would like to use as this:
function setObjectProperties(params, target) {
if (params !== undefined && target !== undefined) {
$.each(params, $.proxy(function (key, value) {
this[key] = value;
}, target));
}
}
Here we tell jQuery to set this to the value of the target parameter, which is set to this inside the object constructor, as shown below:
function User(params) {
this.name = null;
this.email = null;
this.password = null;
setObjectProperties(params, this);
}
One problem still remains, we should check against declared properties on the object to see if we can assign the value passed in:
function setObjectProperties(params, target) {
if (params !== undefined && target !== undefined) {
$.each(params, $.proxy(function (key, value) {
if (this.hasOwnProperty(key)) {
this[key] = value;
}
}, target));
}
}
Here's the full and final code:
function setObjectProperties(params, target) {
if (params !== undefined && target !== undefined) {
$.each(params, $.proxy(function (key, value) {
if (this.hasOwnProperty(key)) {
this[key] = value;
}
}, target));
}
}
function User(params) {
this.name = null;
this.email = null;
this.password = null;
setObjectProperties(params, this);
}
user1 = new User();
// User { name: null, email: null, password: null }
user2 = new User({ name: 'First Last' });
// User { name: "First Last", email: null, password: null }
user3 = new User({ name: 'First Last', age: '400' });
// User { name: "First Last", email: null, password: null }