1. Closure 继承

 

1.1 goog.inherits

goog.inherits = function(childCtor, parentCtor) {



 function tempCtor() { };   // 声明临时函数 tempCtor

 tempCtor.prototype = parentCtor.prototype; // 临时函数的原型指向父构造函数的原型

 childCtor.superClass_ = parentCtor.prototype; //给子对象构造函数添加superClass_属性,指向父对象构造函数的原型对象



 childCtor.prototype = new tempCtor(); // 子对象的原型指向 tempCtor的实例



 childCtor.prototype.constructor = childCtor;   // 子对象原型对象的构建函数指向自己



   //子构造函数绑定base方法,调用父构造函数原型对象方法

 childCtor.base = function(me, methodName, var_args) {



   var args = new Array(arguments.length - 2);

   for (var i = 2; i < arguments.length; i++) {

     args[i - 2] = arguments[i]; //获取参数

   }



   //执行父对象的方法

   return parentCtor.prototype[methodName].apply(me, args);

 };

};

 

通过goog.inherits()完成了:

  1. 干净的继承父构造函数的原型对象.

  2. 增强子构造函数,可以通过childCtor的base方法和所需方法名调用父构造函数原型对象的方法。

  3. 为子构造函数新加了一个属性,指向父构造函数的原型对象。



 

参考链接: https://www.cnblogs.com/vivihoo03/p/5651020.html

1.2 goog.base

base: function (me, opt_methodName, var_args) {

   var caller = arguments.callee.caller; // 这个属性保存着调用当前函数的函数的引用



   if (caller.superClass_) {

       // Copying using loop to avoid deop due to passing arguments object to

       // function. This is faster in many JS engines as of late 2014.

       var ctorArgs = new Array(arguments.length - 1);

       for (var i = 1; i < arguments.length; i++) {

           ctorArgs[i - 1] = arguments[i];

       }

       // This is a constructor. Call the superclass constructor.

       return caller.superClass_.constructor.apply(me, ctorArgs);

   }



   // Copying using loop to avoid deop due to passing arguments object to

   // function. This is faster in many JS engines as of late 2014.

   var args = new Array(arguments.length - 2);

   for (var i = 2; i < arguments.length; i++) {

       args[i - 2] = arguments[i];

   }

   var foundCaller = false;

   for (var ctor = me.constructor;

       ctor; ctor = ctor.superClass_ && ctor.superClass_.constructor) {

       if (ctor.prototype[opt_methodName] === caller) {

           foundCaller = true;

       } else if (foundCaller) {

           return ctor.prototype[opt_methodName].apply(me, args);

       }

   }



   // If we did not find the caller in the prototype chain, then one of two

   // things happened:

   // 1) The caller is an instance method.

   // 2) This method was not called by the right caller.

   if (me[opt_methodName] === caller) {

       return me.constructor.prototype[opt_methodName].apply(me, args);

   } else {

       console.log(

           'goog.base called from a method of one name ' +

           'to a method of a different name');

   }

}