OO Javascript构造函数模式:新古典与原型
我看着我的眼睛 打开了。有一次,他说,“Javascript是优秀程序员认为他们可以有效使用的唯一语言,而不必学习。”然后我意识到,我就是那个人 在那次演讲中,他发表了一些对我来说非常令人惊讶和深刻的言论。例如,JavaScript是地球上最重要的编程语言。或者它是这个星球上最流行的语言。而且,它在很多方面都被严重破坏了 对我来说,他最令人惊讶的一句话是“新的是危险的”。他不再使用它了。他也不使用OO Javascript构造函数模式:新古典与原型,javascript,oop,constructor,class-design,Javascript,Oop,Constructor,Class Design,我看着我的眼睛 打开了。有一次,他说,“Javascript是优秀程序员认为他们可以有效使用的唯一语言,而不必学习。”然后我意识到,我就是那个人 在那次演讲中,他发表了一些对我来说非常令人惊讶和深刻的言论。例如,JavaScript是地球上最重要的编程语言。或者它是这个星球上最流行的语言。而且,它在很多方面都被严重破坏了 对我来说,他最令人惊讶的一句话是“新的是危险的”。他不再使用它了。他也不使用这个 他为Javascript中的构造函数提供了一个有趣的模式,该模式允许私有和公共成员变量,既不依
这个
他为Javascript中的构造函数提供了一个有趣的模式,该模式允许私有和公共成员变量,既不依赖于new
,也不依赖于this
。看起来是这样的:
// neo-classical constructor
var container = function(initialParam) {
var instance = {}; // empty object
// private members
var privateField_Value = 0;
var privateField_Name = "default";
var privateMethod_M1 = function (a,b,c) {
// arbitrary
};
// initialParam is optional
if (typeof initialParam !== "undefined") {
privateField_Name= initialParam;
}
// public members
instance.publicMethod = function(a, b, c) {
// because of closures,
// can call private methods or
// access private fields here.
};
instance.setValue = function(v) {
privateField_Value = v;
};
instance.toString = function(){
return "container(v='" + privateField_Value + "', n='" + privateField_Name + "')";
};
return instance;
}
// usage
var a = container("Wallaby");
WScript.echo(a.toString());
a.setValue(42);
WScript.echo(a.toString());
var b = container();
WScript.echo(b.toString());
编辑:更新代码以切换到小写类名
这种模式是从
问题:您是否使用这种构造函数模式?你觉得可以理解吗?你有更好的吗?在他的书中,它被称为功能继承(52页)。我还没用呢。如果你向道格拉斯学习javascript,这是可以理解的。我认为没有更好的办法。这个很好,因为它:
- 允许程序员创建私有成员
- 保护私人成员的安全并消除这一点,而不是假装隐私(私人成员以ux开始)
- 使继承平滑,没有不必要的代码
然而,它也有一些缺点。您可以在这里了解更多信息:这看起来像的非单例版本,通过利用JavaScript的“闭包”可以模拟私有变量
我喜欢它(有点…)。但我并不认为用这种方法处理私有变量有什么好处,特别是当它意味着(初始化后)添加的任何新方法都无法访问私有变量时
另外,它没有利用JavaScript的原型模型。每次调用构造函数时都必须初始化所有方法和属性-如果构造函数的原型中存储了方法,则不会发生这种情况。事实上,使用传统的构造函数/原型模式要快得多!你真的认为私有变量使性能的提升值得吗
这种模型对于模块模式是有意义的,因为它只被初始化一次(创建一个伪单例),但我不确定它在这里是否有意义
您使用这种构造函数模式吗
不,虽然我使用它的单例变量,模块模式
你觉得可以理解吗
是的,它可读性强,非常清晰,但我不喜欢将所有内容都集中在构造函数中这样的想法
有更好的吗
如果你真的需要私有变量,那么一定要坚持使用它。否则,只需使用传统的构造器/原型模式(除非您与Crockford一样害怕新的
/这个
组合):
与Doug对该主题的观点相关的其他类似问题:
我避免使用这种模式,因为大多数人都觉得阅读起来比较困难。我通常采用两种方法:
- 如果我只有其中之一,那么我使用匿名对象:
var MyObject = {
myMethod: function() {
// do something
}
};
- 对于不止一种情况,我使用标准javascript原型继承
var MyClass = function() {
};
MyClass.prototype.myMethod = function() {
// do something
};
var myObject = new MyClass();
(1) 更容易阅读、理解和书写。(2) 当有多个对象时效率更高。Crockford的代码每次都会在构造函数中创建一个新的函数副本。闭包还有一个缺点,就是调试更加困难
虽然您丢失了真正的私有变量,但按照惯例,您的前缀应该是
\uu
的私有成员
这在javascript中是一个公认的难题,但可以使用调用和应用来正确设置。我也经常使用var self=this
创建一个闭包变量,用作成员函数中定义的函数内的this
MyClass.prototype.myMethod = function() {
var self = this;
// Either
function inner1() {
this.member();
}
inner1.call(this);
// Or
function inner2() {
self.member();
}
inner2();
};
您使用这种构造函数模式吗
早些时候,当我第一次学习JavaScript时,我就使用了这种模式,无意中接触到了道格拉斯·克罗克福德(Douglas Crockford)的文学作品
你觉得可以理解吗
只要您了解闭包,这个方法就很清楚
有更好的吗
这取决于你想完成什么。如果您试图编写一个尽可能防白痴的库,那么我可以完全理解私有变量的用法。它可能有助于防止用户无意中干扰对象的完整性。是的,时间成本可能稍大一些(大约是3倍),但时间成本是一个没有实际意义的论点,直到它真正影响到您的应用程序。我注意到前一篇文章()中提到的测试没有考虑访问对象函数所需的时间
我发现prototype/constructor方法通常会导致更快的构建时间,是的,但它不一定能节省检索时间。使用原型链查找函数比将函数直接附加到正在使用的对象上要付出额外的成本。因此,如果您调用了很多原型函数,而没有构建很多对象,那么使用Crockford的模式可能更有意义
不过,如果我不是为大量读者编写代码,我倾向于不喜欢使用私有变量。如果我所在的团队都是有能力的程序员,我可以相信,如果我自己能很好地编码和注释,他们会知道如何使用我的代码。然后我使用类似于Crockford模式的东西
MyClass.prototype.myMethod = function() {
var self = this;
// Either
function inner1() {
this.member();
}
inner1.call(this);
// Or
function inner2() {
self.member();
}
inner2();
};
var SomeObject = function() {
/* Private access */
var privateMember = "I am a private member";
var privateMethod = bindScope(this, function() {
console.log(privateMember, this.publicMember);
});
/* Public access */
this.publicMember = "I am a public member";
this.publicMethod = function() {
console.log(privateMember, this.publicMember);
};
this.privateMethodWrapper = function() {
privateMethod();
}
};
var o = new SomeObject();
o.privateMethodWrapper();