有关JavaScript的继承:大部分oo语言(如:java)有接口和实现继承二种方式, 在JavaScript中没有接口,只有实现继承,而继承主要通过原型链。那么就从原型链
开始讨论JavaScript的继承。
1 原型链
(1)什么是原型?
先从原型说起:我们知道每一个函数创建之后都有自己的原型对象,函数通过prototype属性指向原型对象。我们创建对象实例,实例也通过内部属性'[[prototype]]'
指向原型对象。原型最大的特点就是共享属性和方法。
(2)什么是'原型搜索机制' ?
我们经常通过实例对象去访问属性 举个例子:obj.name 这就是一个寻找的过程,对象先找自己的实例属性中没有叫name的属性,
如果有就返回name的值。没有, 对象会通过[[prototype]]内部属性访问原型对象中的属性,寻找name属性.这个过程就是原型搜索机制.
(3)什么是原型链?
我们在学习继承之前有没有这么想过: 构造函数的原型是一个实例对象,那么它是由谁创造的? 没有疑问是Object(在没有继承的情况下)。我们知道任何一个实例对象都是有一个内部属性
指向他的原型,object也不例外,它是指向object原型对象的。 我们可以这样证明构造函数的原型对象是object对象并且指向object的原型:
function Person(){}
alert(Person.prototype instanceof Object);//true Object.prototype.isPrototypeOf(Person.prototype); //true
说了那么多,原型对象是Object对象有什么用呢? 看下面代码
function SuperType(){}
SuperType.prototype.getSuperValue=function {return 'Super';};
上面这张图中是构造函数和原型之间的视图。 我们可以看到SuperType构造函数的原型 SuperType.prototype有一个内部属性[[prototype]], 注意看他是
指向Object的原型 Object prototype的。 我们写二行代码:var o=new SuperType(); o.toString(); 会怎么样?
实现: 原型搜索机制通过 o 寻找对象中有没有tostring() 方法 ,显然是没有的; 对象就通过内部属性 [[prototype]] 找到"SuperType prototype"原型对象,
又在这里寻找没有toString这个方法 , 还是没有(此时说明对象没有这个方法),怎么办?不要忘记SuperType prototype是Object的实例,势必也有一个内部属性指向Object原型。所以接着
根据SuperType prototype" 原型对象的[[prototype]] 找到object的原型,在这里再寻找toString(),结果找到了(显然不是对象o的直接方法,而是object的方法)。这就是实现了继承。
而所谓原型链: 就是实例和原型之间的链条不断层层递进(直到object原型为止)。
我们可以很容易发现: 任何自定义类型都继承object, 因为原型链的终端是Object prototype; 再拿内置对象String来说,他的原型对象也是指向Object prototype的;
2 原型链实现继承
思路: 将子类构造函数的原型指向父类的实例对象,就实现继承了
举个例子说明:
function SuperType(){} //父类
SuperType.prototype.getSuperValue=function(){return '123'};
function SubType={this.subproterty = false;}
SubType.prototype=new SuperType(); //原型链继承;
SubType.prototype.getSubValue=function(){return '456'}; //再为子类添加方法
var instance=new SubType(); //创建子类对象;
alert(instance.getSuperValue()); // 123;
ps : 上面这张图展示了实例对象,原型,构造函数之间的关系! 根据原型链不难理解这张图
下面还有而2个重要的问题,在这里就不解释了。 都是要理解javascript的继承机制,那么一定要明白!
3 原型链继承有什么问题吗?
4 最常使用的继承方式: 原型链继承 结合 '借用构造函数’方式
5 扩展性问题:什么是'原型式继承'?