除了`goog.inherits()`之外,为什么`goog.base(this)`是必要的?

时间:2012-06-20 15:12:14

标签: javascript inheritance prototypal-inheritance google-closure-library

在这个涉及构造函数的Google Closure javascript代码片段中,为什么goog.base(this);是必需的? Foo {/ 1}}是否已从[Disposable]继承goog.inherits(foo, goog.Disposable);

goog.provide('Foo');

/**
 * @constructor
 * @extends {goog.Disposable}
 */
Foo = function() {
  goog.base(this);
}     
goog.inherits(foo, goog.Disposable);

foo.prototype.doSomething = function(){
  ...
}

foo.prototype.disposeInternal = function(){
  ...
}

3 个答案:

答案 0 :(得分:9)

goog.inherits(childConstructor, parentConstructor)

goog.inherits()从子构造函数建立原型链 到父构造函数。

/**
 * Inherit the prototype methods from one constructor into another.
 * @param {Function} childCtor Child class.
 * @param {Function} parentCtor Parent class.
 */
goog.inherits = function(childCtor, parentCtor) {
  /** @constructor */
  function tempCtor() {};
  tempCtor.prototype = parentCtor.prototype;
  childCtor.superClass_ = parentCtor.prototype;
  childCtor.prototype = new tempCtor();
  /** @override */
  childCtor.prototype.constructor = childCtor;
};


除了原型属性之外,构造函数可能具有“自己的”属性 (即添加到this的特定于实例的属性)。自goog.inherits()以来 不调用父构造函数,自己的属性不会被复制到 子构造函数和父级中的任何初始化代码都没有 执行。由于这些原因,标准模式为chain constructors,如下例所示。

/**
 * @param {string} name The parent's name.
 * @constructor
 */
var Parent = function(name) {
  /**
   * @type {string}
   * @private
   */
  this.name_ = name;
}

/**
 * @param {string} name The child's name.
 * @constructor
 * @extends {Parent}
 */
var Child = function(name) {
  Parent.call(this, name);
}
goog.inherits(Child, Parent);


goog.base(self, opt_methodName, var_args)

goog.base()是一个帮助函数,用于调用父方法,以便您这样做 无需明确使用call()apply()

  

如果从构造函数调用[goog.base()],则调用   带参数1-N的超类构造函数。

     

如果从原型方法调用此方法,则必须传递名称   该方法作为此函数的第二个参数。如果你不,   你会得到一个运行时错误。这会调用超类的方法   论证2-N。

     

此功能仅在您使用goog.inherits表示继承时有效   你的班级之间的关系。

在Closure代码中,通常使用goog.base()来链接构造函数 而不是明确地调用父构造函数。

/**
 * @param {string} name The child's name.
 * @constructor
 * @extends {Parent}
 */
var Child = function(name) {
  goog.base(this, name);
}
goog.inherits(Child, Parent);


进一步阅读

答案 1 :(得分:1)

在JavaScript中,this完全取决于函数的调用方式,而不是它定义的位置(就像在Java,C#和C ++中一样)。因此,要在中this goog.Disposable的调用是您调用它的this,您必须使用.call或{ {1}}。否则,如果您刚刚拨打.apply,则来电goog.Disposable()将为this

基本上,有两种方法可以为您正在调用的函数设置goog

  1. 使用thisobj.func()表示法 - 例如,将调用作为从对象检索属性的同一整体表达式的一部分。这告诉引擎在通话中,您希望obj["func"]()引用this

  2. 通过提供用作obj作为第一个参数的对象,使用callapply更加明确。 thiscall之间的唯一区别在于您提供其他参数:使用apply,您可以将它们作为离散参数提供,例如call调用foo.call(obj, 1, 2, 3)foo设置为this,参数obj12。使用3,您可以将参数作为类似于数组的第二个参数提供:apply(注意foo.apply(obj, [1, 2, 3]);[;例如]

    < / LI>

    更多探索:

答案 2 :(得分:1)

你可以看到

Foo = function() {
  goog.base(this); //call parent constructor
}     
goog.inherits(foo, goog.Disposable);

如:

public class Foo extends Disposable(){
  public Foo(){
    super(); // call parent constructor
  }
}