Javascript 从“原型”和“新”转向封闭和曝光模式
我一直在重新分解其他人的JavaScript代码 之前:Javascript 从“原型”和“新”转向封闭和曝光模式,javascript,design-patterns,closures,prototypal-inheritance,Javascript,Design Patterns,Closures,Prototypal Inheritance,我一直在重新分解其他人的JavaScript代码 之前: function SomeObj(flag) { var _private = true; this.flag = (flag) ? true : false; this.version="1.1 (prototype)"; if (!this._someProperty) this._init(); // leading underscore hints at what shoul
function SomeObj(flag) {
var _private = true;
this.flag = (flag) ? true : false;
this.version="1.1 (prototype)";
if (!this._someProperty) this._init();
// leading underscore hints at what should be a 'private' to me
this.reset(); // assumes reset has been added...
}
SomeObj.prototype.reset = function() {
/* perform some actions */
}
/* UPDATE */
SomeObj.prototype.getPrivate = function() {
return _private; // will return undefined
}
/* ...several other functions appended via `prototype`...*/
var SomeObj = function (flag) {
var _private = true;
this.flag = (flag) ? true : false;
this.version = "2.0 (constructor)";
this.reset = function () {
/* perform some actions */
};
/* UPDATE */
this.getPrivate = function() {
return _private; // will return true
}
/* other functions and function calls here */
}
之后:
function SomeObj(flag) {
var _private = true;
this.flag = (flag) ? true : false;
this.version="1.1 (prototype)";
if (!this._someProperty) this._init();
// leading underscore hints at what should be a 'private' to me
this.reset(); // assumes reset has been added...
}
SomeObj.prototype.reset = function() {
/* perform some actions */
}
/* UPDATE */
SomeObj.prototype.getPrivate = function() {
return _private; // will return undefined
}
/* ...several other functions appended via `prototype`...*/
var SomeObj = function (flag) {
var _private = true;
this.flag = (flag) ? true : false;
this.version = "2.0 (constructor)";
this.reset = function () {
/* perform some actions */
};
/* UPDATE */
this.getPrivate = function() {
return _private; // will return true
}
/* other functions and function calls here */
}
对我来说,第一个例子看起来很难阅读,尤其是在更大的背景下。使用prototype
属性,像这样添加reset
之类的方法,似乎不太受控制,因为它可能发生在脚本中的任何地方。我的重构代码(上面的第二个示例)看起来更整洁,因此更易于阅读,因为它是自包含的。我通过变量声明获得了一些隐私,但我失去了原型链的可能性
问题:
function SomeObj(flag) {
var _private = true;
this.flag = (flag) ? true : false;
this.version="1.1 (prototype)";
if (!this._someProperty) this._init();
// leading underscore hints at what should be a 'private' to me
this.reset(); // assumes reset has been added...
}
SomeObj.prototype.reset = function() {
/* perform some actions */
}
/* UPDATE */
SomeObj.prototype.getPrivate = function() {
return _private; // will return undefined
}
/* ...several other functions appended via `prototype`...*/
var SomeObj = function (flag) {
var _private = true;
this.flag = (flag) ? true : false;
this.version = "2.0 (constructor)";
this.reset = function () {
/* perform some actions */
};
/* UPDATE */
this.getPrivate = function() {
return _private; // will return true
}
/* other functions and function calls here */
}
prototype
,我还损失了什么,或者原型链的损失是否有更大的影响。6岁,但声称使用原型
属性在大规模上比闭包模式更有效new
操作符实例化;他们都是“经典”式的构造器。最后,我甚至想从这个模型中转移到一个模型中,在这个模型中,所有的属性和函数都声明为var
s,我有一个方法,我公开了这个方法,它能够返回一个对象,打开我需要的所有属性和方法,这些属性和方法对那些私有的属性和方法具有特权(通过闭包)。大概是这样的:
var SomeObj = (function () {
/* all the stuff mentioned above, declared as 'private' `var`s */
/* UPDATE */
var getPrivate = function () {
return private;
}
var expose = function (flag) {
// just returns `flag` for now
// but could expose other properties
return {
flag: flag || false, // flag from argument, or default value
getPrivate: getPrivate
}
};
return {
expose: expose
}
})(); // IIFE
// instead of having to write `var whatever = new SomeObj(true);` use...
var whatever = SomeObj.expose();
关于StackOverflow,有一些答案可以回答“原型vs.闭包”的问题(例如)。但是,与prototype
属性一样,我感兴趣的是朝着这个方向移动并远离new
操作符对于我的代码效率和任何可能性损失(例如instanceof
丢失)意味着什么。如果我不打算使用原型继承,那么在前面的new
操作符中我真的丢失了什么吗原型
和新的
真的是最有效的方式,比闭包有更多的优势(无论你认为它们可能是什么),那么是否有任何指导方针或设计模式可以更简洁地编写它们expose
每次都返回一个新对象,因此这就是实例化发生的地方。正如我所理解的,当该对象引用在SomeObj
闭包中声明的方法时,它们在所有对象中都是相同的方法(除非被覆盖)。对于标志
变量(我现在已经更正了该变量),可以从expose
的参数继承,使用默认值,或者再次引用封装的预先存在的方法或属性。因此,有一些对象的实例正在生成,这里有一些继承(加上多态性?)
所以重复问题2:如果我不打算使用原型继承,那么在前面的new
操作符中我真的丢失了什么吗
非常感谢您迄今为止的回答,这些回答帮助我澄清了问题。根据我的经验,不使用
。prototype
会丢失的唯一东西是内存-每个对象最终都拥有其中定义的函数对象的自己的副本
如果您只打算实例化“少量”的对象,那么这不太可能是一个大问题
关于你的具体问题:
new
,如果您希望从中实例化对象,那么它就没有用了prototype
中使用reset
方法意味着您的构造函数的所有实例都将共享该方法的完全相同的副本。通过在构造函数中创建本地方法,每个实例将有一个方法副本,这将消耗更多内存(如果有很多实例,这可能会成为一个问题)。除此之外,两个版本是相同的;将function SomeObj
更改为var SomeObj=function
仅在父作用域上提升SomeObj
的方式不同。你说你“通过变量声明获得了一些隐私”,但我没有看到任何私有变量
new
关键字。但是,您将失去拥有构造函数的能力原型
,我还损失了什么
我相信有人能提供答案,但我至少要试一试。使用原型至少有两个原因:
prototype
方法可以静态使用
它们只创建一次
将方法创建为对象成员意味着为对象的每个实例创建该方法。这意味着每个对象有更多的内存,并且会减慢对象的创建速度(从而提高效率)。人们倾向于说prototype
方法类似于类方法,而成员方法类似于对象方法,但这是非常误导的,因为prototype链中的方法仍然可以使用对象实例
哟