我不喜欢 javascript 的一件事是有数百种方法可以做事。我想知道的是如何声明一个类?我是否使用 function() 方法?我调用 Class.create() 吗?什么是“标准做法”?声明成员函数的“标准做法”是什么?我使用原型吗?我使用 myClass.method() 吗?最后,我如何进行基本的父子继承?我问的原因是因为在互联网上我收到了很多方法来做这些事情。我想知道什么是“标准做法”。
3 回答
我的建议是阅读Stoyan Stefanov 的JavaScript 模式。他详细介绍了这个主题。
就个人而言,我更喜欢Module Pattern。它减少了全球空间污染,并且易于使用。
编辑:
其他答案在实例化他们的“类”时省略了new
关键字。请参阅答案383503,了解有关正确实例化 JavaScript“类”的详细讨论。
在 Javascript 中声明类,特别是子类没有“标准实践”的原因是 Javascript 实际上没有对 C++ 中典型类的内置语法语言支持。相反,它有自己的一套技巧来生成类似的功能,并且有很多不同的方式来表达这些技巧。真的没有标准的方法。
我发现最好使用更常见的 javascript 库之一(jQuery、Prototype、YUI、Closure 等),然后使用它们提供的函数进行子类化,这将为您提供自己的“标准”方式它。如果您不想使用其中一个库,则需要从某处借用一些代码进行子类化(相当于 YUI 的 extend() 函数),然后决定要使用哪种样式。
我个人认为,在大型项目、多人参与的项目或打算由其他人扩展的项目中,Javascript 的一个弱点是没有“方法”来声明类和子类的语言语法。相反,拥有一致的代码库的唯一方法是自己决定要使用哪种声明风格,然后将其作为项目中的编码标准强制执行,就像使用大括号样式或缩进一样风格。
绝对同意您所描述的内容没有“标准做法”的其他海报。我将分享我现在使用的东西,这类似于 Douglas Crawford 在他的书 The Good Parts中使用的东西。我并没有声称它是完美的,但是我对这个问题感到很沮丧很长一段时间,当我希望以 OOP 方式组织 JS 代码时,这对我来说效果很好。
var ParentClass = function () {
var my = {}, // store private member variables and functions
that = {}; // store public member variables and functions
my.privateVar = 0;
that.publicVar = 7;
// this won't be visible outside of parent class,
// even to children unfortunately
my.getPrivateVar = function () {
return my.privateVar;
};
my.privateFunction = function () {
// do stuff
};
// this will be visible to children classes and anyone
// else using ParentClass
that.parentFunction = function () {
// here we can access private vars and functions
my.privateVar++;
my.privateFunction();
};
// and here we return the object that we created
// to store the public member variables and functions
return that;
};
var ChildClass = function () {
var my = {}, // more private vars and functions will live here
that = ParentClass(); // and here we subclass ParentClass;
// here define more public, private methods as before
that.childFunction = function () {
};
return that;
};
// test drive it
var cc = ChildClass();
cc.parentFunction();
cc.childFunction();
console.debug(cc.publicVar);
// console.debug(cc.privateVar); // undefined