Javascript 为什么除了“goog.inherits()”,还需要“goog.base(this)”呢?

Javascript 为什么除了“goog.inherits()”,还需要“goog.base(this)”呢?,javascript,inheritance,prototypal-inheritance,google-closure-library,Javascript,Inheritance,Prototypal Inheritance,Google Closure Library,在这段涉及构造函数的Google闭包javascript代码中,为什么goog.base(this)必要吗?不Foo已经通过goog.inherits(Foo,goog.Disposable)从Disposable继承 goog.provide('Foo'); /** *@constructor *@extends{goog.Disposable} */ Foo=函数(){ 高基(本); } goog.继承(foo,goog.一次性); foo.prototype.doSomethin

在这段涉及构造函数的Google闭包javascript代码中,为什么
goog.base(this)必要吗?不
Foo
已经通过
goog.inherits(Foo,goog.Disposable)从Disposable继承

goog.provide('Foo');
/**
*@constructor
*@extends{goog.Disposable}
*/
Foo=函数(){
高基(本);
}     
goog.继承(foo,goog.一次性);
foo.prototype.doSomething=函数(){
...
}
foo.prototype.disposeInternal=函数(){
...
}

在JavaScript中,
这个
完全由函数的调用方式设置,而不是由函数的定义位置设置(如Java、C#和C++)。因此,要使
this
在调用
goog.Disposable
中成为调用它的位置的
this
,您必须使用
.call
.apply
。否则,如果您刚刚调用了
goog.Disposable()
,那么在调用
中,这将是
goog

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

  • 使用
    obj.func()
    obj[“func”]()
    表示法-例如,在从对象检索属性的同一个整体表达式中进行调用。这会告诉引擎,在调用中,您希望
    This
    引用
    obj

  • 使用
    call
    apply
    将对象作为
    this
    用作第一个参数,从而更明确地说明它。
    call
    apply
    之间唯一的区别是如何提供其他参数:使用
    call
    ,您将它们作为离散的参数提供,例如
    foo.call(obj,1,2,3)
    调用
    foo
    ,将
    设置为
    obj
    ,并将参数
    1
    2
    3
    。使用
    apply
    ,可以像第二个参数那样将参数作为数组提供:
    foo.apply(obj[1,2,3])(注意
    [
    ]
    ;例如
    变量a=[1,2,3];foo.call(obj,a);

  • 更多信息可供探索:

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

    /**
    *将原型方法从一个构造函数继承到另一个构造函数中。
    *@param{Function}childCtor子类。
    *@param{Function}parentCtor父类。
    */
    goog.inherits=函数(childCtor、parentCtor){
    /**@constructor*/
    函数tempCtor(){};
    tempCtor.prototype=parentCtor.prototype;
    childCtor.superClass=parentCtor.prototype;
    childCtor.prototype=新的tempCtor();
    /**@覆盖*/
    childCtor.prototype.constructor=childCtor;
    };
    

    除了原型属性外,构造函数还可能具有“自己的”属性 (即,将特定于实例的属性添加到
    )。因为
    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()
    是一个辅助函数,用于调用父方法,以便 不需要显式地使用或

    如果从构造函数调用[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);
    

    进一步阅读
    • (参见第6章:“代码重用模式”,了解用于实现goog.inherits()-经典模式#5-临时构造函数)的模式的详细分析)
      • 您可以看到

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


        你能给出一个标准的答案吗?这样我们就可以把它作为复制品,我看到你每天给出100次这个答案:D@Esailija:是的,令人惊讶的是,它在许多不同的上下文中出现。:-)有时它是完全重复的,其他时候(就像这个)它实际上是重复的,但你可以看到为什么有些人没有找到更早的答案……作为一个来自
        Java
        世界的人,说
        base
        继承
        ,就像
        super()
        扩展
        一样,这有意义吗?
        
        public class Foo extends Disposable(){
          public Foo(){
            super(); // call parent constructor
          }
        }