覆盖toString方法 - 公共/私有访问

时间:2015-04-21 11:06:28

标签: javascript prototype tostring

我创建了一个基本库,如下所示:

(function () {
    function Store() {
        var store = [];

        if (!(this instanceof Store)) {
            return new Store();
        }

        this.add = function (name, price) {
            store.push(new StoreItem(name, price));
            return this;
        };
    }

    function StoreItem(name, price) {
        if (!(this instanceof StoreItem)) {
            return new StoreItem();
        }

        this.Name = name || 'Default item';
        this.Price = price || 0.0;
    }

    Store.prototype.toString = function () {
        // build a formatted string here
    };

    StoreItem.prototype.toString = function () {
        return this.Name + ' $' + this.Price;
    };

    window.shop = window.shop || {
        Store: function () {
            return new Store();
        }
    };
}());

绝大部分效果都很好!但是,我不想暴露Store构造函数中定义的store数组,因为我不想在此库的控件之外修改它。

但是,相反,我想覆盖Store的{​​{1}}方法来使用toString数组中的StoreItem s所以我可以使用store方法返回所有StoreItem s的格式化字符串。

E.g。如果toString被曝光,store方法将类似于:

toString

无论如何我可以在不公开我的Store.prototype.toString = function () { return this.store.join('\r\n'); }; // shop.Store().add('Bread', 2).add('Milk', 1.5).toString() result: // Bread $2 // Milk $1.5 数组的情况下实现这一目标吗?

2 个答案:

答案 0 :(得分:2)

您可以为每个Store提供自己的.toString方法,有权通过关闭访问本地store变量 - 就像使用.add一样:

function Store() {
    if (!(this instanceof Store)) {
        return new Store();
    }
    var store = [];

    this.add = function(name, price) {
        store.push(new StoreItem(name, price));
        return this;
    };
    this.toString = function () {
        return store.join('\n');
    };
}

或者,您无论如何都必须定义某种访问器方法,或者如果您只能添加它而不读它,那么store将毫无用处。有些东西需要显示商店项目,需要迭代它们,需要测试它们的可用性......如果你创建一个通用的访问器,可能是某种迭代器的形式(带回调的each方法?),那么.prototype.toString方法也可以使用它。

答案 1 :(得分:1)

通过添加返回字符串化store并从store调用它的公共方法,可以保留原型toString方法,同时保护Store.prototype.toString

下面我将this.getStoreString添加到构造函数中,并从原始toString调用它。

(function () {
    function Store() {
        var store = [];

        if (!(this instanceof Store)) {
            return new Store();
        }

        this.add = function (name, price) {
            store.push(new StoreItem(name, price));
            return this;
        };

        // new method
        this.getStoreString = function(){
            return store.join('\r\n');  
        };
    }

    function StoreItem(name, price) {
        if (!(this instanceof StoreItem)) {
            return new StoreItem();
        }

        this.Name = name || 'Default item';
        this.Price = price || 0.0;
    }

    Store.prototype.toString = function () {
        // call the new method
        return this.getStoreString();
    };

    StoreItem.prototype.toString = function () {
        return this.Name + ' $' + this.Price;
    };

    window.shop = window.shop || {
        Store: function () {
            return new Store();
        }
    };
}());

<强> Fiddle

@ Bergi的答案似乎更简单,但这显示了另一种选择。