我试图在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个实例的对象。我正在努力理解,如果有人能够启发我会非常感激吗?
使用此方法有任何性能优势吗?
答案 0 :(得分:3)
我不明白的是,当这个对象被启动时,新的Foo()会每次为自动执行函数创建一个新的对象吗?
没有。这就是原型的重点,它们不会重复 - 每个Foo
实例都将从同一个Foo.prototype
对象继承。
有人可以解释一下我的项目使用它的好处和不足。
看起来你对命名有一点误解:那些“私有”的东西不是“属性”或“方法”,因为它们与实例对象完全无关。它们只是局部变量,只能从分配给原型对象的函数中访问。
您可能希望在How do JavaScript closures work?中阅读IIFEs及其用法。
这种类型的模式如何适用于可能有500个实例或只有1个的对象。
完全没问题。但是,仅使用1个实例的构造函数模式可能有点奇怪 - 可以用更简单的方式定义单例。
如果您想了解有关该模式的更多信息,请搜索revealing prototype pattern - 这是用于创建原型对象的revealing module pattern。
答案 1 :(得分:2)
我之前没有见过这种模式,使用prototype
的模块(就是它所谓的)...但这是我推荐的内容;它很相似,但模块包含了所有内容:
var Foo = (function FooClass() {
var privateVar = 'Hello world';
function privateFunc() {
...
}
function Foo() {}
Foo.prototype = {
publicMethod: function() {
...
}
};
return Foo;
}());
var foo = new Foo();
我不明白的是当这个对象被启动时新的Foo() 这样做每次都会为原型创建一个新对象 自执行功能?
自执行功能运行一次,返回对象,不再运行;它通过闭包来保持对变量的引用。
答案 2 :(得分:0)
我不明白的是,当这个对象被启动时,新的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
属性也保持不变。