如何仅传入属性来实例化JavaScript对象?

时间:2015-06-01 18:55:14

标签: javascript oop

我想要一个包含这样字段的对象:

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 }

最简单的方法是什么?我只能想为每个房产做一个有条件的。

4 个答案:

答案 0 :(得分:2)

function (params) {
    var properties = ['id', 'name', ..];
    for (var i = 0, length = properties.length; i < length; i++) {
        var property = properties[i];
        if (params[property]) {
            this[property] = params[property];
        }
    }
}

答案 1 :(得分:1)

除了有条件地添加它们之外别无他法,但你可以简化它。

由于JavaScript是一种动态类型的语言,并且它还强制执行duck-typing,因此不要指望像 classes 那样可以自动神奇地阻止添加意外属性。

有关可能的简化,请参阅以下代码段。

 def token_exchange
   exchangeTokenResponse = API.exchange_token(public_token)
   self.access_token = exchangeTokenResponse.access_token
   self.accounts = API.set_user(access_token, ['auth'])
   self.transactions = API.set_user(access_token, ['connect'])
   self.save
 end
function BaseObject() {}

BaseObject.prototype = {
  defineRequiredProperties: function(requiredProperties, propertyMap) {
    if (!(requiredProperties instanceof Array)) {
      throw Error("'requiredProperties` argument must be an array!");
    }

    if (typeof propertyMap == "object") {
      var that = this;

      Object.keys(propertyMap).forEach(function(propertyName) {
        // Better do this because you'll be able to check if a 
        // property exists even if it's defined in the prototype chain
        if (requiredProperties.indexOf(propertyName) > -1) {
          that[propertyName] = propertyMap[propertyName];
        }
      });
    }
  }
};

// As OP requested, this prevents this custom function from being iterated.
// It's still callable but not enumerable
Object.defineProperty(BaseObject.prototype, "defineRequiredProperties", {
    enumerable: false
});

function User(params) {
  this.defineRequiredProperties(["id", "name"], params);
}

// This is effecitvely derive BaseObject (actually, chaining the
// BaseObject prototype) in order to share defineRequiredProperties
// across all your custom prototypes and be DRY (Don't Repeat Yourself)
User.prototype = Object.create(BaseObject.prototype);

var user = new User({
  id: 11,
  name: "Matías",
  lastName: "Fidemraizer"
});

document.getElementById("result").textContent = JSON.stringify(user);

答案 2 :(得分:1)

真诚地,你不需要条件。你的尝试完全没问题。只需执行以下代码:

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对象将完全符合您的要求:

  

User {id: 123}

答案 3 :(得分:-3)

如何使用传递的属性扩展用户属性?这样,任何新内容都将添加到用户。 http://api.jquery.com/jquery.extend/