昨天已经讲到了goog.inherits(),主要负责通过为子构造函数原型对象通过原型链继承父构造函数的原型对象的方法,完成继承。这样继承只完成了原型对象的继承,看看之前的那张图:
是不是感觉父构造函数好像没什么用处啊,还记得上篇文章,构建一个超级对象的设想吗?这个要依赖另一个API,goog.base().
在看源代码之前让我们看看一个简单的demo,温习一下goog.inherit(),这个demo还可以帮助我们了解goog.base()可以做些什么。
demo代码:
输出结果:
分析:
先把goog.inherit()和goog.base()放在一边,让我们先分析一下这三个构造函数:A,B,C。
A:
构造函数:为new(构造)出来的新对象添加name属性,并取名周杰伦。
原型对象:添加details方法,并在控制台输出调用该方法的对象的name的老婆是昆凌。
(不排除有人使用call,apply等方法冒充周杰伦。。。)
B:
构造函数:为new(构造)出来的新对象添加age属性,并赋值为24。
原型对象:添加details方法,并在控制台输出,调用该方法的对象的name属性的值的是一名歌手,年龄为该对象属性age的值。
这里有个疑问:该构造函数创建出来的对象是不足以执行其原型对象的方法,简而言之,如果我们用B构造函数创建一个对象,这个对象是没有name属性,如果后面不给该对象添加name属性,而去调用details的方法,在该对象中找不到name属性从而产生错误。
C:
构造函数:为new(构造)出来的新对象添加height属性,并复制为“173cm”。
原型对象:details方法,输出调用该方法的对象的妈妈是叶惠美,身高为该对象的height属性值。
这里与B相似,通过C构造函数构造出来的对象也是不足以满足其原型对象的details的方法,因为C构造出来的对象没有name属性。
然后让我们分析一下结果:
person对象是通过A构造函数构造出来的,但是存在下列疑惑:
1.Person对象为什么同时拥有,B构造函数,和C构造函数中为新对象添加的属性?
2.为什么调用Person对象的details方法的时候不仅执行了构造函数A原型对象的details方法,同时还执行了B和C的原型对象的同名方法?
这就是goog.base的威力。
goog.base()主要有2种使用情况:
1.在构造函数中使用,比如:
先看作用:
找到A继承的父构造函数B,并将当前作用域对象传入B构造函数,并调用。这就可以解释疑惑1中Person对象拥有B构造函数构建的age属性,同时B中又将A中的作用域对象(Person)传入并调用了其父构造函数C,所以person对象又有了height属性。
2.在构造函数原型对象的方法中使用,比如:
在这里,goog.base()的第二个参数是需要调用该原型对象constructor指向的构造函数继承的父构造函数的原型对象的方法名,所以这就很好的解释了疑惑2,为什么执行了B原型对象,同时在B中又调用goog.base()所以又执行了C原型对象的details方法。
这一章我们主要是,做了一个简单的demo,并分析了goog.base()的两个主要用途,及其效果,下面一章我们将着重分析goog.base()的源码。