为什么`goog.base(本)`除了`goog.inherits()`有必要吗?(Why is `

2019-09-18 07:11发布

在这个片段谷歌闭幕的JavaScript涉及构造函数代码,为什么goog.base(this); 必要? 不Foo已经从一次性继承与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(){
  ...
}

Answer 1:

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(个体经营,opt_methodName,var_args)

goog.base()是调用父方法的辅助功能,让您无需显式地使用()调用或应用() 。

如果[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);


延伸阅读

  • 在JavaScript中继承模式由迈克尔·博林
  • )goog.base的检查(由迈克尔·博林
  • 封闭:由迈克尔·博林权威指南
  • JavaScript的模式由斯托扬斯特凡 (见第六章:“代码重用的模式”为用于实现该模式的详细分析goog.inherits() - 经典模式#5 -一个临时构造函数


Answer 2:

在JavaScript中, this是由函数是如何调用全部设置,而不是在那里的定义(因为它是用Java,C#和C ++)。 因此,为了使this调用 goog.Disposablethis地方你调用它,你必须使用.call.apply 。 否则,如果你只是叫goog.Disposable()呼叫内thisgoog

基本上有两种方式来设置this为你调用该函数:

  1. 使用obj.func()obj["func"]()符号-例如,拨打电话为你在哪里从检索对象的属性相同的整体表现的一部分。 这告诉调用中,你想要的引擎thisobj

  2. 使用callapply通过提供对象使用更加明确一下this作为第一个参数。 之间的唯一区别callapply是如何提供其他参数:使用call时,需要提供他们作为离散ARGS,如foo.call(obj, 1, 2, 3)调用foothis设置为obj和参数12 ,和3 。 与apply ,你提供的参数作为数组状的第二个参数: foo.apply(obj, [1, 2, 3]); (注意[] ;例如var a = [1, 2, 3]; foo.call(obj, a);

更多的探索:

  • 神话方法
  • 你必须记住this


Answer 3:

你可以看到

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

如:

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


文章来源: Why is `goog.base(this)` necessary in addition to `goog.inherits()`?