Javascript 子类访问父类';s闭包变量
我正在为我当前的项目使用John Resig的继承实现,我想知道是否有一种方法让子类也继承(访问)父类的闭包变量 例如,我编写了以下类Javascript 子类访问父类';s闭包变量,javascript,Javascript,我正在为我当前的项目使用John Resig的继承实现,我想知道是否有一种方法让子类也继承(访问)父类的闭包变量 例如,我编写了以下类 var Foo = (function() { var p = "im p"; var Foo = Class.extend({ getp : function() { return p; } }); return Foo; })(); 现在Foo类可以访问闭包中的变量p。Foo的子类也是 var Ba
var Foo = (function() {
var p = "im p";
var Foo = Class.extend({
getp : function() {
return p;
}
});
return Foo;
})();
现在Foo类可以访问闭包中的变量p。Foo的子类也是
var Bar = Foo.extend({});
var bar = new Bar;
bar.getp(); // "im p"
这并不奇怪,因为bar.getp只是调用Foo.getp,Foo.getp可以访问p。但是如果我覆盖bar.getp
var Bar = Foo.extend({
getp : function() {
return p;
}
});
现在,当我执行bar.getp()时,它将抛出未定义的p,因为bar无法访问它
我有几种方法可以让p访问bar,但我认为它们有点笨拙,您认为这是实现这一点的最干净的方法。
p
变量仅在自执行匿名Foo
函数的范围内定义,因此无法检索它
将其视为私有成员,它也仅在声明它的类中可用
如果您只需要检索它-您可以执行以下操作:
var Bar = Foo.extend({
getp : function() {
var p = Foo.prototype.getp.call(this);
return p;
}
});
p
变量仅在自执行匿名Foo
函数的范围内定义,因此无法检索该变量
将其视为私有成员,它也仅在声明它的类中可用
如果您只需要检索它-您可以执行以下操作:
var Bar = Foo.extend({
getp : function() {
var p = Foo.prototype.getp.call(this);
return p;
}
});
闭包范围包括定义函数时范围内的任何内容。在这种情况下,定义第一个
getp
时,p
在范围内,但定义第二个getp
时不在范围内。所以你不能引用p
。事实上,您可能已经发现,第一个getp
方法引用的p
实际上对所有Foo
对象(及其子类)都是通用的
JavaScript实际上不太适合“私有变量”。通常,开发人员在不需要继承时使用闭包范围的变量,或者在需要继承时使用某种约定,例如添加下划线,如下所示:
var Foo = Class.extend({
_p : "i'm p",
getp : function() {
return this._p;
}
});
var Bar = Foo.extend({
getpete : function() {
return Foo.getp() + "ete";
//You can also use this.getp() if you want, there's no difference.
}
});
然后您可以毫不费力地创建子类:
var Bar = Foo.extend({
getp : function() {
return this._p;
}
});
现在,我还应该注意到,你的例子非常做作,而且做作的方式有点毫无意义。我的意思是,为什么要用同样返回p
的东西覆盖getp()
?如果您的意图是实际创建一个私有的静态属性p
,那么您所拥有的应该可以正常工作。如果您想访问子类中的p
,您应该只使用您有权访问的getp
方法,如下所示:
var Foo = Class.extend({
_p : "i'm p",
getp : function() {
return this._p;
}
});
var Bar = Foo.extend({
getpete : function() {
return Foo.getp() + "ete";
//You can also use this.getp() if you want, there's no difference.
}
});
希望有帮助 闭包范围包括定义函数时范围内的任何内容。在这种情况下,定义第一个
getp
时,p
在范围内,但定义第二个getp
时不在范围内。所以你不能引用p
。事实上,您可能已经发现,第一个getp
方法引用的p
实际上对所有Foo
对象(及其子类)都是通用的
JavaScript实际上不太适合“私有变量”。通常,开发人员在不需要继承时使用闭包范围的变量,或者在需要继承时使用某种约定,例如添加下划线,如下所示:
var Foo = Class.extend({
_p : "i'm p",
getp : function() {
return this._p;
}
});
var Bar = Foo.extend({
getpete : function() {
return Foo.getp() + "ete";
//You can also use this.getp() if you want, there's no difference.
}
});
然后您可以毫不费力地创建子类:
var Bar = Foo.extend({
getp : function() {
return this._p;
}
});
现在,我还应该注意到,你的例子非常做作,而且做作的方式有点毫无意义。我的意思是,为什么要用同样返回p
的东西覆盖getp()
?如果您的意图是实际创建一个私有的静态属性p
,那么您所拥有的应该可以正常工作。如果您想访问子类中的p
,您应该只使用您有权访问的getp
方法,如下所示:
var Foo = Class.extend({
_p : "i'm p",
getp : function() {
return this._p;
}
});
var Bar = Foo.extend({
getpete : function() {
return Foo.getp() + "ete";
//You can also use this.getp() if you want, there's no difference.
}
});
希望有帮助 在javascript中模拟类通常被认为不是最佳的。最好使用它的本机功能以获得最佳效果。@RobG:基于原型的继承中有什么不是本机的?@zerkms您的评论有点混乱,原型在大多数类仿真方案中都有一定程度的使用,否则您基本上只剩下闭包,关键是不要纯粹为了模仿经典继承而使用它们。私有成员、特权方法、super、getter和setter等都可以模拟,但最好是模拟它们的行为,而不是实际的特性(希望有意义)。在javascript中模拟类通常被认为不是最佳的。最好使用它的本机功能以获得最佳效果。@RobG:基于原型的继承中有什么不是本机的?@zerkms您的评论有点混乱,原型在大多数类仿真方案中都有一定程度的使用,否则您基本上只剩下闭包,关键是不要纯粹为了模仿经典继承而使用它们。私有成员、特权方法、super、getter和setter等都可以被模拟,但最好是模拟它们的行为,而不是实际的特性(希望这是有意义的)。实际上,p是我项目中singleton类的实例,我有很多。我想要一种干净的方式在Foo(GameEngine类)及其子类(ClientGameEngine类)中使用它们。最简单的方法是生成那些单例类全局变量,我这样做只是为了避免这种情况。@yngum是的,那么你应该使用我的最后一个示例。在父类中创建必要的getter和setter(您可以在父类中访问闭包范围),但在扩展类时引用它们。您不需要在子类中重新创建
getp
和setp
(如果存在的话)。实际上,p是我的项目中singleton类的实例,我有很多。我想要一种干净的方式在Foo(GameEngine类)及其子类(ClientGameEngine类)中使用它们。最简单的方法是让那些单例类的全局,