【发布时间】:2015-02-17 09:23:19
【问题描述】:
来自 C++/Objective-C 背景,我正在尝试学习如何正确有效地重现 Javascript 中的继承和封装模式。我已经阅读了大量资料(Crockford 等),虽然有很多关于如何实现其中一个或另一个的示例,但我正在努力解决如何在不引入重大负面影响的情况下将它们结合起来。
目前,我有这个代码:
var BaseClass = (function() {
function doThing() {
console.log("[%s] Base-class's 'doThing'", this.name);
}
function reportThing() {
console.log("[%s] Base-class's 'reportThing'", this.name);
}
return function(name) {
var self = Object.create({});
self.name = name;
self.doThing = doThing;
self.reportThing = reportThing;
return self;
}
}());
var SubClass = (function(base) {
function extraThing() {
console.log("[%s] Sub-class's 'extraThing'", this.name);
}
function doThing() {
console.log("[%s] Sub-class's replacement 'doThing'", this.name);
}
return function(name) {
// Create an instance of the base object, passing our 'name' to it.
var self = Object.create(base(name));
// We need to bind the new method to replace the old
self.doThing = doThing;
self.extraThing = extraThing;
return self;
}
}(BaseClass));
它大部分做我想做的事:
// Create an instance of the base class and call it's two methods
var base = BaseClass("Bert");
base.doThing(); // "[Bert] Base-class's 'doThing'"
base.reportThing(); // "[Bert] Base-class's 'reportThing'"
var other = BaseClass("Fred");
// Create an instance of the sub-class and call it's three methods (two from the base, one of it's own)
var sub = SubClass("Alfred");
sub.doThing(); // "[Alfred] Sub-class's replacement 'doThing'"
sub.extraThing(); // "[Alfred] Sub-class's 'extraThing'"
sub.reportThing(); // "[Alfred] Base-class's 'reportThing'"
但是,有(至少!)两个问题:
- 我不相信原型链是完整的。如果我通过子类的一个实例替换原型中的方法,其他实例看不到它:
- .name 属性没有封装
我正在替换原型的函数实现,如下所示:
Object.getPrototypeOf(oneInstance).reportThing = function() { ... }
otherInstance.reportThing() // Original version is still called
这也许不是什么大问题,但它让我怀疑自己的理解。
私有变量是我想要有效实现的东西。变量隐藏的模块模式在这里没有帮助,因为它导致函数定义存在于每个对象中。我可能错过了一种组合模式的方法,那么有没有一种方法可以在不复制函数的情况下实现私有变量?
【问题讨论】:
-
“我正在努力学习如何正确有效地重现 Javascript 中的继承和封装模式”——不要假设你从 C++ 中知道的模式在 JavaScript 中也能有效工作。
-
@joews 我不认为会有 1:1 的对应关系,但由于绝对可以单独合并这两种模式,我希望有一种干净的方式来组合它们。
-
对我来说,这是 JavaScript 最烦人的方面之一,以至于很多人都想在上面强制执行他们的 Java / C++ 习惯。
-
我并不是想保持这样的习惯。我很高兴能够以最佳方式构建代码,但我没有看到我想要模仿的任何概念的缺点。
标签: javascript inheritance encapsulation