2

我试图在 javascript 中复制私有原型方法并找到这段代码,但我并不完全理解它是如何实现自身的。

代码是...

var Foo = function () {};  

Foo.prototype = (function () {  

    // Private attributes  
    var somePrivateAttribute = 'Hello world';  

    // Private methods  
    function somePrivateMethod(val) {  
        alert(val);  
    }  

    // Public attributes and methods  
    return {  
        somePublicMethod: function () {  
            somePrivateMethod(somePrivateAttribute);  
        }  
    };  
})(); 

我不明白的是,当这个对象被启动new Foo()时,它是否每次都会为原型创建一个新对象,因为它是在一个自执行函数中?谁能解释在我的项目中使用它的好处和坏处。

这种类型的模式如何适用于可能有 500 个实例或只有 1 个实例的对象。我正在努力理解,如果有人能启发我,我将不胜感激?

使用这种方法有什么性能优势吗?

4

3 回答 3

3

我不明白的是,当这个对象被启动时 new Foo() 是否每次都为原型创建一个新对象,因为它是在一个自执行函数中?

不,这就是原型的意义所在,它们不是重复的——你的每个Foo实例都将继承自同一个Foo.prototype对象。

谁能解释在我的项目中使用它的好处和坏处。

关于命名,您似乎有点误解:那些“私有”事物不是“属性”或“方法”,因为它们与实例对象完全无关。它们只是局部变量,只能从您分配给原型对象的函数中访问。

您可能想阅读JavaScript 闭包是如何工作的?以及它们在IIFE中的用途。

这种类型的模式如何适用于可能有 500 个实例或只有 1 个实例的对象。

完全没问题。但是,仅对 1 个实例使用构造函数模式可能有点奇怪 - 可以以更简单的方式定义单例。

如果您想了解有关该模式的更多信息,请搜索显示原型模式- 它是用于创建原型对象的显示模块模式。

于 2013-04-14T23:20:48.933 回答
2

我以前没有见过那种模式,使用一个模块(这就是它的名字)prototype......但这是我推荐的;它很相似,但模块包含所有内容:

var Foo = (function FooClass() {

  var privateVar = 'Hello world';  

  function privateFunc() {
    ...
  }

  function Foo() {}

  Foo.prototype = {
    publicMethod: function() {
      ...
    }
  };

  return Foo;

}());

var foo = new Foo();

我不明白的是,当这个对象被启动时 new Foo() 是否每次都为原型创建一个新对象,因为它是在一个自执行函数中?

自执行函数运行一次,返回对象,不再运行;它通过闭包保持对变量的引用。

于 2013-04-14T23:18:58.973 回答
0

我不明白的是,当这个对象被启动时 new Foo() 是否每次都为原型创建一个新对象,因为它是在一个自执行函数中?

不,对 Foo 原型的赋值只发生一次。完全没有问题,只是有点不合常规。

你也可以这样写(也是非常规的,但完成同样的事情):

var Foo = function () {};  

Foo.prototype = new function() {  

    // Private attributes  
    var somePrivateAttribute = 'Hello world';  

    // Private methods  
    function somePrivateMethod(val) {  
        alert(val);  
    }  

    // Public attributes and methods  

    this.constructor = Foo;

    this.somePublicMethod = function () {  
        somePrivateMethod(somePrivateAttribute);  
    }  
}; 

正如Bergi 指出的那样,这为原型链添加了一个额外的对象;如果你想避免这种情况,你可以这样写:

var Foo = function () {};  

(function() {  

    // Private attributes  
    var somePrivateAttribute = 'Hello world';  

    // Private methods  
    function somePrivateMethod(val) {  
        alert(val);  
    }  

    // Public attributes and methods  

    this.somePublicMethod = function () {  
        somePrivateMethod(somePrivateAttribute);  
    }

}).call(Foo.prototype) 

通过修改原型而不是替换它,该constructor属性也保持不变。

于 2013-04-14T23:33:58.603 回答