本文实例讲述了javascript模拟实现继承的方法。分享给大家供大家参考。具体分析如下:
我们都知道,在javascript中只能模拟实现oo中的类,也就意味着,在javascript中没有类的继承。我们也只能通过在原对象里添加或改写属性来模拟实现。
先定义一个父类,
//父类function parentclass() { this.classname = parentclass; this.auth = auth; this.version = v1.0; this.parentclassinfo = function () { return this.classname + \n + this.auth + \n + this.version; }}
一、prototype 实现:
//子类//1、prototype继承function childclassbyprototype() { this.date = 2013-07-26; this.classinfo = function () { return this.parentclassinfo() + \n + this.date; }}childclassbyprototype.prototype = new parentclass();var cctest1 = new childclassbyprototype();cctest1.parentclassinfo();cctest1.classinfo();
这种方式很简单,只需把父类的实例赋值给子类的prototype属性就行了,然后子类就可以使用父亲的方法和属性了。这里其实是用到了原型链向上查找的特性,比如这个例子中的 cctest1.parentclassinfo() 方法,javascript会先在childclassbyprototype的实例中查找是否有parentclassinfo()方法,子类中没有,所以继续查找childclassbyprototype.prototype属性,而其prototype属性的值是parentclass的一个实例,该实例有parentclassinfo()方法,于是查找结束,调用成功。
二、apply 实现:
//2、apply继承function childclassbyapply() { parentclass.apply(this, new array()); //parentclass.apply(this, []); this.date = 2013-07-26; this.classinfo = function () { return this.parentclassinfo() + \n + this.date; }}
javascript中的apply可以理解为用a方法替换b方法,第一个参数为b方法的对象本身,第二个参数为一个数组,该数组内的值为需要传递给a方法对应的参数列表,如果参数为空,即没有参数传递,可通过 new array()、[] 来传递。
三、call + prototype 实现:
//3、call+prototype继承function childclassbycall() { parentclass.call(this, arguments); this.date = 2013-07-26; this.classinfo = function () { return this.parentclassinfo() + \n + this.date; }}childclassbycall.prototype = new parentclass();
call和apply作用类似,即都是用a方法替换b方法,只是传递的参数不一样,call方法的第一个参数为b方法的对象本身,后续的参数则不用array包装,需直接依次进行传递。既然作用差不多,为何多了一句 原型赋值呢?这是因为call方法只实现了方法的替换而没有对对象属性进行复制操作。
每种方法都有其适用环境,比如,如果父类带有有参构造函数:
function parentclass(classname, auth, version) { this.classname = classname; this.auth = auth; this.version = version; this.parentclassinfo = function () { return this.classname + \n + this.auth + \n + this.version; }}
这种情况下,prototype就不适用了,可选用apply或call;
function childclassbyapply(classname, auth, version) { parentclass.apply(this, [classname, auth, version]); this.date = 2013-07-26; this.classinfo = function () { return this.parentclassinfo() + \n + this.date; }}function childclassbycall(classname, auth, version) { parentclass.call(this, arguments[0], arguments[1], arguments[2]); //parentclass.call(this, classname, auth, version); this.date = 2013-07-26; this.classinfo = function () { return this.parentclassinfo() + \n + this.date; }}childclassbycall.prototype = new parentclass();
实例化:
var cctest2 = new childclassbyapply(parentclass, auth, v1.0);var cctest3 = new childclassbycall(parentclass, auth, v1.0);
在apply和call中,又该如何取舍呢?在oo的继承中,子类继承于父类,那么它应该也是父类的类型。即,childclassbycall、childclassbyapply应该也是parentclass类型,但我们用instanceof检测一下就会发现,通过apply继承的子类,并非parentclass类型。所以,我们建议用call + prototype 来模拟实现继承。据说,google map api 的继承就是使用这种方式哟。
希望本文所述对大家的javascript程序设计有所帮助。