你的位置:首页 > Java教程

[Java教程]原型与继承学习笔记3


该节思路及部分代码插图摘自 王福朋的博客 第4,5小节(尊重原创也方便自己查阅O(∩_∩)O哈哈~)

 

本打算一天讨论完的问题,刚好有个周末无心学习,再加上真正写出来的时候远没有自己理解的时候想的那么简单,最后横跨4天,罪过/(ㄒoㄒ)/~~

闲话不多说了,按原计划这节说说__proto__以及与prototype更深层的关系,下节计划看看继承有什么以前没注意到的问题。OK,go!

    __proto__是什么

在第一节的讨论学习中我们知道了,每个函数都有一个prototype,每个对象都有__proto__,每个对象的__proto__指向创建他的函数的prototype,这几句总结对于记忆和理解很有帮助。举个栗子:

可以看出来,obj的__proto__和Object的prototype是全等的!这是因为obj={}相当于obj=new Object();,obj实质是由Object实例化的对象,也佐证了上文我们得到的观点。

但还是有个特例,Object.prototype.__proto__是指向null的,这点需要记住。

还有一个问题,第一节我们根据定义得到了,函数也是对象,那么函数有自己的__proto__属性吗?当然有!我们一起分析一下

 

1 function fn(x,y){2    return(x+y);3 }4 console.log(fn(1,2))    //35 6 7 var newFn = new Function('x','y','return(x+y);');8 console.log(newFn(1,2))     //3

 

第二种函数创建的方法使用Function构造函数创建的,只是为了说明一个问题,函数作为对象也是由函数创建的,那么根据上文的总结分析,对象的__proto__指向创建他的那个函数的prototype,我们不难得出:Object.__proto__===Function.prototype,甚至是这样Function.__proto__===Function.prototype。到这是不是可以根据我们那句总结很好的理解这个__proto__了,那么问题又来了,我们也知道函数的prototype属性也是个对象,那么这个对象是不是由所有对象的超类Object创建的呢,答案是肯定的,所以有:Function.prototype.__proto__===Object.prototype.

    对象原型组成的链条-原型链

在我们实际的开发和学习过程中,免不了用到这个操作符:instanceof,具体用法回顾一下:

1 function Fn(){};2 3 var fn1=new Fn();4 fn1 instanceof Fn;    //true5 fn1 instanceof Object;    //true

 

fn1是Fn的实例化对象,那结果为true我们不意外,那为什么Object的测试结果也为true呢,好,我们先分析一下这个操作符:

(图片来源http://www.ibm.com/developerworks/cn/web/1306_jiangjj_jsinstanceof/figure1.jpg)

我们可以看到两条常规线条,一条是对象原型__proto__(命名为A线),一条是函数原型属性prototype(B线),那么

沿着A的__proto__这条线来找,同时沿着B的prototype这条线来找,如果两条线能找到同一个引用,即同一个对象,那么就返回true。如果找到终点还未重合,则返回false。这样我们就不难得出fn1 instanceof Object为true,而且通过这种不断上溯的方式我们也能推出这几个恒等式:

1 Function instanceof Function;2 Object instanceof Function;3 Function instanceof Object;4 Object instanceof Object;

 

 

总结一下:

Function作为一个函数是由他本身Function创建的,Function作为一个对象是由Object创建的,Object作为一个函数由Function创建,Object作为一个对象也由他本身Object创建。现在函数和对象的关系理清了吧,函数也是对象,这句话很重要。

所以说instanceof讲的就是一种原型链的关系,通过这种看不见的链条来判断继承关系,下节我们一起来关注一下继承和原型链的暧昧关系。