5

在这个涉及构造函数的 Google Closure javascript 代码片段中,为什么goog.base(this);需要?还没有Foo从 Disposable with 继承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(){
  ...
}
4

3 回答 3

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() 不调用父构造函数,因此不会将自己的属性复制到子构造函数,并且不会执行父构造函数中的任何初始化代码。由于这些原因,标准模式是链接构造函数,如下例所示。

/**
 * @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表示类之间的继承关系时才有效。

在闭包代码中,通常使用链接构造函数goog.base()而不是显式调用父构造函数。

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


延伸阅读

于 2012-06-20T20:13:26.363 回答
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
  }
}
于 2013-09-09T01:21:00.003 回答
1

在 JavaScript 中,this完全取决于函数的调用方式,而不是定义的位置(就像在 Java、C# 和 C++ 中一样)。因此,要this 调用中goog.Disposable成为this你调用它的地方,你必须使用.callor .apply。否则,如果您刚刚调用goog.Disposable(),则调用范围内this将是goog

基本上,有两种方法可以this为您调用的函数进行设置:

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

  2. 通过提供要用作第一个参数的对象来使用callapply更明确地说明它。和this之间的唯一区别是您如何提供其他参数:使用,您将它们作为离散参数提供,例如使用set to和参数、和的调用。使用,您将参数作为类似数组的第二个参数提供:(注意and ;例如callapplycallfoo.call(obj, 1, 2, 3)foothisobj123applyfoo.apply(obj, [1, 2, 3]);[]var a = [1, 2, 3]; foo.call(obj, a);

更多探索:

于 2012-06-20T15:15:55.630 回答