从构造上的参数设置任意对象属性

时间:2013-06-28 13:05:08

标签: javascript jquery oop

在Javascript中实例化对象时,我想启用以下方案:

  • 可以在没有任何参数的情况下实例化对象,并使用默认属性值
  • 创建
  • 可以使用设置对象属性
  • 的初始值的参数来实例化对象

解决方案应该:

  • 未指定尚未在对象上定义的属性
  • 允许设置任意数量的属性(无,部分或全部)
  • 很容易应用于脚本定义的任何对象,这意味着我们不知道可以设置哪些属性。

jQuery可以使用,但欢迎使用纯JS解决方案。

采用以下对象构造函数:

function User() {
    this.name = null;
    this.email = null;
    this.password = null;
}

解决方案应该让我实现以下目标:

new User();
// User { name: null, email: null, password: null }

new User(<parameter(s) that specify a value for name, email and password>);
// User { name: "passed value", email: "passed value", password: "passed value" }

new User(<parameter that specifies a value for name>);
// User { name: "passed value", email: null, password: null }

new User(<parameter(s) that specify values for name and non-existent property age>);
// User { name: "passed value", email: null, password: null }

2 个答案:

答案 0 :(得分:2)

$.extend()与默认对象结合使用非常简单:

function User(options) {
    var defaults = {
        name: null,
        email: null,
        password: null
    };
    var options = $.extend({}, defaults, options);
    console.log(options);

}

new User(); 
// null, null, null

new User({name : 'First'});
// First, null, null

new User({name : 'First', email: 'users.name@users-email.com'});
// First, users.name@users-email.com, null

new User({name : 'First', email: 'users.name@users-email.comm', password : 'password1'});
// First, users.name@users-email.com, password1

这里有效:http://jsfiddle.net/m6KQC/2/

如果您不想添加在调用函数时传递的额外属性,则只需使用下面的代码而不是$.extend()。它具有与原始功能相同的功能:

function setObjectProperties(defaults, options, target) {
    var options = options || {};
    for (var prop in defaults) { 
        target[prop] = (typeof options[prop] === "undefined") ?  defaults[prop] : options[prop];
    }
}

您可以将其包装在原始函数中并使用它:

setObjectProperties(defaults, options, this);

您可以在此处看到此备选方案:http://jsfiddle.net/m6KQC/9/

答案 1 :(得分:0)

首先,我允许对象构造函数采用参数

function User(params) {
...

要允许提供任意数量的参数,params参数将接受对象文字:

new User({name: 'name 1', id: 1});

接下来,我将params对象传递给一个泛型函数,该函数将处理从params对象到target对象的属性分配。

function setObjectProperties(params, target) {
}

setObjectProperties函数需要验证我们是否已正确传递了一些数据。它会检查paramstarget是否都已定义:

function setObjectProperties(params, target) {
    if (params !== undefined && target !== undefined) {

    }
}

一旦我们确信我们可以使用某些东西,就可以迭代参数并分配给对象属性了。

function setObjectProperties(params, target) {
    if (params !== undefined && target !== undefined) {
        $.each(params, function (i, property) {
            this[i] = property;
        }, target);
    }
}

使用jQuery的$.each函数,它迭代对象属性而没有迭代所有对象属性(如原型等)的副作用。这有效但意味着我们需要处理{{的副作用1}}在this函数的回调闭包内重新定义。我们现在不再知道原始对象是什么了。

然而,jQuery的$.each函数旨在允许我们在指定我们想要用作$.proxy的内容时调用函数:

this

这里我们告诉jQuery将function setObjectProperties(params, target) { if (params !== undefined && target !== undefined) { $.each(params, $.proxy(function (key, value) { this[key] = value; }, target)); } } 设置为目标参数的值,该参数在对象构造函数中设置为this,如下所示:

this

仍然存在一个问题,我们应该检查对象的声明属性,看看我们是否可以分配传入的值:

function User(params) {
    this.name = null;
    this.email = null;
    this.password = null;

    setObjectProperties(params, this);
}

以下是完整和最终的代码:

function setObjectProperties(params, target) {
    if (params !== undefined && target !== undefined) {
        $.each(params, $.proxy(function (key, value) {
            if (this.hasOwnProperty(key)) {
                this[key] = value;
            }
        }, target));
    }
}