2

我正在为我当前的项目使用 John Resig 的继承实现,我想知道是否有办法让子类也继承(访问)父类的闭包变量......

例如,我写了下面的类

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,后者可以访问 p。但是,如果我覆盖 bar.getp

var Bar = Foo.extend({
  getp : function() {
    return p;
  }
});

现在当我执行 bar.getp() 时,它会抛出 p 未定义,因为 bar 无法访问它

我有几种方法可以让 bar 可以访问 p,但我认为它们有点尴尬,你认为最干净的方法是实现这一点。

4

2 回答 2

2

p变量只定义在自执行匿名Foo函数的范围内,所以没有办法取回。

将其视为私有成员,它也仅在它声明的类中可用。

如果您只需要检索它 - 您可以这样做:

var Bar = Foo.extend({
  getp : function() {
    var p = Foo.prototype.getp.call(this);
    return p;
  }
});
于 2012-09-10T03:21:40.400 回答
2

闭包范围由定义函数时范围内的任何内容组成。在这种情况下,定义p第一个时在范围内getp,但在getp定义第二个时不在范围内。所以不能参考p。事实上,您可能已经发现,p第一种方法引用的getp方法实际上对所有Foo对象(及其子类)都是通用的。

JavaScript 并不能很好地适用于“私有变量”。通常,开发人员最终会在不需要继承时使用闭包范围的变量,或者在需要继承时使用某种约定,例如添加下划线,如下所示:

var Foo = Class.extend({  
    _p : "i'm p",
    getp : function() {
        return this._p;
    }
 });

然后你可以毫无困难地进行子类化:

var Bar = Foo.extend({  
    getp : function() {
        return this._p;
    }
});

现在,我还应该指出,您的示例非常做作,并且设计得有点毫无意义。我的意思是,为什么要覆盖getp()也只是返回的东西p?如果您的意图是实际创建一个私有的静态属性p,那么您所拥有的应该可以正常工作。如果您想p在子类中访问,您应该只使用getp您有权访问的方法,如下所示:

var Bar = Foo.extend({  
    getpete : function() {
        return Foo.getp() + "ete"; 
        //You can also use this.getp() if you want, there's no difference.
    }
});

希望有帮助!

于 2012-09-10T03:37:47.663 回答