2

如果您需要创建大量方法,那么使用原型作为方法是有好处的,那么当您使用在构造函数中关闭“this”的方法创建对象时,您是否会获得相同的效果和好处?

请参阅以下代码:

(function(){


    var Planet = function(){

        var self = this;


        var API = {
            publicInterfaceMethodA:function(){
                self.privateProtoMethodA();
            },

            publicInterfaceMethodB:function(){}
        };

        return API;

    };



    Planet.prototype = {

        privateProtoMethod:function(){  },
        privateProtoMethodA:function(){  },
        privateProtoMethodB:function(){  },
        privateProtoMethodC:function(){  },
        privateProtoMethodD:function(){  },
        privateProtoMethodE:function(){  }

    };


    var mars = new Planet();




}());

假设我在原型上有 100 个“私有”方法,对于我创建的每个实例,我只想公开这几个公共 api 方法,但我想保留将原型用于内部方法的好处,这样我就不会“复制”为每个创建的实例提供100 个“this”方法。

据我所知,这不是人们通常的做法,我是否在这里遗漏了一些东西,或者您是否获得了相同的好处而不在构造函数中返回“this”并暴露整个原型?

谢谢

4

2 回答 2

1

当我开始认真做 JS 开发的时候,我也经常使用var self = this;,因为我在各种 jQuery 教程中已经习惯了,我也尝试过你的方法和其他的方法来模拟私有方法。

就个人而言,我不再喜欢两者了。虽然这确实mars不是 的实例Planet,但在我看来,这不是一个真正的问题,因为我通常测试 api 功能,而不是经常测试对象是某个构造函数的实例。

对于私有方法/成员:当您的项目增长并变得更大时,您可能想要开始进行单元测试。例如,如果您有100私有方法并且只有 10公共方法,那么创建好的单元测试可能会变得非常有问题。对于单元测试,您希望测试尽可能少的依赖项。这就是为什么我改变主意并更喜欢用 jsdoc 创建一个清晰的 api 文档,使用注释来标记方法/成员(如果它们是私有的,而不是过度隐藏它们)。

有时,它不仅可以根据情况替换公共方法,还可以替换私有方法。

您的方法肯定有一些有效的情况,但如果您只是使用它来保护功能不被滥用,您可能应该考虑一下。

var self = this;:只要someFunction.bind(element)不会造成性能问题,我更喜欢使用bind(有一个适用于旧浏览器的polyfill)。有了它,您可以避免例如回调的深度嵌套,并且您不需要记住您需要使用预期 关键字self的位置。this

于 2013-10-17T18:48:58.213 回答
0

这样的事情怎么样?

(function(){
    var Planet = function(){
        var self = this;
        self.constructor.methods = {
            A: function(){ console.log('Constructor Method A called'); },
            B: function(){  },
            C: function(){  },
            D: function(){  },
            E: function(){  }
        };

        var API = {
            publicInterfaceMethodA: function(){
                return self.constructor.methods.A.call(this);
            },

            publicInterfaceMethodB: function(){}
        };

        return API;
    };

    var mars = new Planet();
    mars.publicInterfaceMethodA();
}());

这些方法附加到Planet函数,然后由mars实例调用。

于 2013-10-17T17:18:00.357 回答