google closure继承模块三: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');
}
}
goog.base的代码其实并不复杂,
var caller = arguments.callee.caller;
caller是执行goog.base()这个方法的函数名称。通过判断函数是否有superClass_的属性,来区分是否此函数是子构造函数。
(superClass_这个属性就是之前goog.inherit()埋下的伏笔,不仅可以通过这个属性访问父构的原型对象,还可以判断执行goog.base()的函数是否为构造函数)
如果是自构造函数,就把当前子构造函数的this对象和agruments传递给父构造函数,调用父构造函数。通过在自构造函数中调用goog.base(this);
即可以让通过子构造函数创建出来的对象,拥有父构造函数创建出来的一些属性。
这就是为什么之前通过那个只有一个name属性显示“周杰伦”的构造函数A创建出来的新对象,拥有构造函数B,和C创建的一些属性。
(这里需要注意,在调用构造函数必须先用goog.inherit(childCtor,parentCtor)建立起继承关系。)
如果不是子构造函数的话,那么就是另一种可能性就是自构造函数原型对象中的方法。
var args = new Array(arguments.length - 2);
for (var i = 2; i < arguments.length; i++) {
args[i - 2] = arguments[i];
}
这时候goog.base()的前两个参数一个为作用域对象,一个则是方法名称,剩下的则为传入方法的参数,args即为提取出需要传入方法的参数,
目的是调用继承的父构造函数的原型对象的方法,第二个参数即为调用的方法名称,这个方法名称一般设为调用
goog.base()的子原型对象方法的名称(方法继承)。
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);
}
}
这一段稍微有点绕,但是目的明确,看起来就不是那么晦涩了,首先ctor为原型对象constructor指向的子构造函数,
if (ctor.prototype[opt_methodName] === caller) {
foundCaller = true;
}
这段代码是为了检查子构原型对象的方法和调用继承的父构圆形对象的方法是否同名。然后通过
ctor = ctor.superClass_ && ctor.superClass_.constructor
通过superClass_属性,找到父构造函数的原型对象,然后constructor指向的当然是父构造函数,都是存在的。所以
return ctor.prototype[opt_methodName].apply(me, args);
即调用父构造函数原型对象的同名方法。(此时的ctor为子构造函数superClass_指向的父构造函数)
google closure继承模块三:goog.base()源码分析的更多相关文章
- Java 序列化和反序列化(三)Serializable 源码分析 - 2
目录 Java 序列化和反序列化(三)Serializable 源码分析 - 2 1. ObjectStreamField 1.1 数据结构 1.2 构造函数 2. ObjectStreamClass ...
- Vert.x系列(三)--ClusteredEventBus源码分析
前言:因为ClusteredEventBus涉及集群,有必产生网络问题,从而引入了NetServer.ServerID等涉及网络,端口的类.在之前的EventBusImpl中, 使用的数据结构是以ad ...
- 一个普通的 Zepto 源码分析(三) - event 模块
一个普通的 Zepto 源码分析(三) - event 模块 普通的路人,普通地瞧.分析时使用的是目前最新 1.2.0 版本. Zepto 可以由许多模块组成,默认包含的模块有 zepto 核心模块, ...
- ABP源码分析三:ABP Module
Abp是一种基于模块化设计的思想构建的.开发人员可以将自定义的功能以模块(module)的形式集成到ABP中.具体的功能都可以设计成一个单独的Module.Abp底层框架提供便捷的方法集成每个Modu ...
- 一个普通的 Zepto 源码分析(二) - ajax 模块
一个普通的 Zepto 源码分析(二) - ajax 模块 普通的路人,普通地瞧.分析时使用的是目前最新 1.2.0 版本. Zepto 可以由许多模块组成,默认包含的模块有 zepto 核心模块,以 ...
- 一个普通的 Zepto 源码分析(一) - ie 与 form 模块
一个普通的 Zepto 源码分析(一) - ie 与 form 模块 普通的路人,普通地瞧.分析时使用的是目前最新 1.2.0 版本. Zepto 可以由许多模块组成,默认包含的模块有 zepto 核 ...
- 【JUC】JDK1.8源码分析之ReentrantLock(三)
一.前言 在分析了AbstractQueuedSynchronier源码后,接着分析ReentrantLock源码,其实在AbstractQueuedSynchronizer的分析中,已经提到过Ree ...
- 【JUC】JDK1.8源码分析之ArrayBlockingQueue(三)
一.前言 在完成Map下的并发集合后,现在来分析ArrayBlockingQueue,ArrayBlockingQueue可以用作一个阻塞型队列,支持多任务并发操作,有了之前看源码的积累,再看Arra ...
- 【JUC】JDK1.8源码分析之AbstractQueuedSynchronizer(二)
一.前言 在锁框架中,AbstractQueuedSynchronizer抽象类可以毫不夸张的说,占据着核心地位,它提供了一个基于FIFO队列,可以用于构建锁或者其他相关同步装置的基础框架.所以很有必 ...
随机推荐
- mysql中文乱码问题解决
在mysql5.0以上,中文乱码不能用网上的大多数方法,我用网上改编码的问题,让我mysql服务器再也起不起来了. 我用的mysql5.7.16绿色免安装版. 在根目录下的配置文件里my.ini(或者 ...
- 详解 $_SERVER 函数中QUERY_STRING和REQUEST_URI区别(转)
对于php$_SERVER这个全局变量 ,里面有很多的参数,慢慢的熟悉 1,http://localhost/aaa/ (打开aaa中的index.php)结果:$_SERVER['QUERY_STR ...
- Android中Context详解
大家好, 今天给大家介绍下我们在应用开发中最熟悉而陌生的朋友-----Context类 ,说它熟悉,是应为我们在开发中时刻的在与它打交道,例如:Service.BroadcastReceiver.A ...
- PHP Fatal Error: call to undefined function mysql_connect() [duplicate]
You shouldn't use mysql_* functions to start with. They are deprecated as of PHP 5.5. Use mysqli or ...
- Skyfree退休公告
Skyfree退休公告 https://www.itsk.com/thread-372142-1-1.html Skyfree 发表于 2016-11-14 12:26:51 本以为到了这天,会有很多 ...
- mysql-5.7.9安装
版本:mysql-5.7.9-linux-glibc2.5-x86_64.tar.gz(编译版本) 解压: tar -zxvf mysql-5.7.9-linux-glibc2.5-x86_64.ta ...
- Appium 服务关键字
Appium 服务关键字 关键字 描述 实例 automationName 你想使用的自动化测试引擎 Appium (默认) 或 Selendroid platformName 你要测试的手机操作系统 ...
- match() vs search()
match() 函数只检查 RE 是否在字符串开始处匹配,而 search() 则是扫描整个字符串.记住这一区别是重要的.记住,match() 只报告一次成功的匹配,它将从 0 处开始:如果匹配不是从 ...
- python爬取返利网中值得买中的数据
先使用以前的方法将返利网的数据爬取下来,scrapy框架还不熟练,明日再战scrapy 查找目标数据使用的是beautifulsoup模块. 1.观察网页,寻找规律 打开值得买这块内容 1>分析 ...
- ajax向后台传递数组
$.ajax({ traditional: true//这个设置为true,data:{"steps":["qwe","asd"," ...