Javascript:创建一个对象构造函数

Javascript: Creating an object constructor

本文关键字:构造函数 一个对象 创建 Javascript      更新时间:2023-09-26

我有一个对象构造函数,我定义了一个使用 json-object 作为输入参数为对象属性设置新值的方法,我的解决方案正在工作,但我怀疑是否有最好的方法可以做到这一点?

任何使用 OOP 的答案将不胜感激。


这是我的代码:

//Object constructor
function searchOption(o) {
   o = o || {};
   this.Word = o.Word || "";
   this.SubCategories = o.SubCategories || [];
   this.Page = o.Page || 1;
   this.Sort = o.Sort || "desc";
   this.ItemsView = o.ItemsView || 18;
   //Method to set new values, preserving untouched properties
   this.set = function (x) { $.extend(this, x); };
}
(function() {
    var search = new searchOption({ Word:"canela", ItemsView:6 });
    console.log(search);
    search.set({ Word:"VIAJE", Page:3, Sort:"asc" });
    console.log(search);
})();

我会从构造函数中删除this.set方法并改用prototype

//Object constructor
function searchOption(o) {
   o = o || {};
   this.Word = o.Word || "";
   this.SubCategories = o.SubCategories || [];
   this.Page = o.Page || 1;
   this.Sort = o.Sort || "desc";
   this.ItemsView = o.ItemsView || 18;
}
//Method to set new values, preserving the untouched properties
searchOption.prototype.set = function(x) {
    searchOption($.extend(this, x));
}
由于

$.extend()扩展了第一个传递的对象,因此您甚至不需要在set方法中再次调用构造函数

searchOption.prototype.set = function(x) {
    $.extend(this, x);
};

在这里小提琴:http://jsbin.com/eHodoqA/1/edit

注意:

如果您也希望合并SubCategories - true作为第一个参数传递给将触发深度克隆的$.extend(请参阅 http://api.jquery.com/jQuery.extend/#jQuery-extend-deep-target-object1-objectN)

在内存消耗方面有更好的方法,因为您可以通过 prototype 在实例之间共享默认值。这同样适用于函数。

可以使用帮助程序函数来实现此新设计,该函数仅在所需成员未undefined或与默认值不同时才复制这些成员。

此外,由于约定构造函数以大写字母开头,属性通常为 lowerCamelCased。这些命名约定被广泛使用,我强烈建议您遵循它们。

显示以下设计是为了学习目的,除非您计划拥有大量SearchOption实例,否则不需要

function applyConfig(obj, config, props) {
    var i = 0,
        len = props.length,
        k, v;
    for (; i < len; i++) {
        if (
            config.hasOwnProperty(k = props[i]) && typeof (v = config[k]) !== 'undefined' //ingore undefined values
            //let default values be shared between instances
            && v !== obj[k]
        ) {
            obj[k] = v;
        }
    }
}
function SearchOption(config) {
    config = config || {};
    //handle all immutable values
    applyConfig(this, config, ['word', 'page', 'sort', 'itemsView']);
    this.subCategories = config.subCategories || [];
}

SearchOption.prototype = {
    constructor: SearchOption,
    //keeping default values on the prototype is memory efficient
    //since they get shared between instances, however we should only use
    //this approach for immutable values.
    word: '',
    page: 1,
    sort: 'desc',
    itemsView: 18,
    //it's better to have functions on the prototype too
    set: function (values) {
        //not sure why you were doing searchOptions(...)? It looks very wrong
        //since the function will get executed in the global object's context (window)
        //note that with the following, we will shadow any default prototype
        //values, unlike when we called the constructor.
        $.extend(this, values);
    }
};
var so1 = new SearchOption(), //share same word
    so2 = new SearchOption(), //share same word
    so3 = new SearchOption({
        word: 'test'
    });
console.log('so1:', so1.word, 'so2:', so2.word, 'so3:', so3.word);
console.log(so1);