本文主要是讲解如何通过prototype实现JavaScript继承,并逐步循序渐进,最终实现一个继承的通用函数。
1.首先我们定义一个父类Father,如下所示:
function Father(){ this.name = "姓名"; this.age = "20"; this.setName = function(str){this.name=str}; this.getName = function(){return this.name;}; } Father.prototype.setAge = function(age){this.age = age;}; Father.prototype.getAge = function(){return this.age;}; console.log(new Father());运行结果如下:
可以看到Father具有age、name两个属性以及getName、setName、getAge、setAge四个方法,但是要注意的是setAge、getAge方法是放在Father.prototype中的,prototype中的方法是公共方法,也就是说在创建新的实例时,prototype中的内容不会随着新实例的创建而占用更多的内存,所以公共方法最好放到prototype中。而实例中的setName与getName方法是在实例中的,每当新实例创建时,每个新实例都会额外占用内存来存储这两个方法。
2.使用call(context,para1...)尝试实现继承
代码如下:
function Sun1(){ Father.call(this); } console.log(new Sun1())
3.尝试使用apply(context,arguments)尝试实现继承
代码如下:
function Sun2(){ Father.apply(this,arguments); } console.log(new Sun2());
4.通过更改prototype实现继承
代码如下:
function Sun3(){} Sun3.prototype = new Father(); Sun3.prototype.constructor = Sun3; console.log(new Sun3());
5.继承函数的实现
既然我们知道了如何通过prototype来实现继承,那么我们就可以将该实现封装成一个函数,使得代码可重用,代码如下:
function inherit(child,parent){ child.prototype = new parent(); child.prototype.constructor = child; } function Sun4(){} inherit(Sun4,Father); console.log(new Sun4());运行结果如下:
6.面向对象的通用继承的实现
虽然上文已经通过inherit函数实现了继承函数,但是在使用时每次都要把父子两个类传递进去,还不够面向对象,为了更好的模拟面向对象的特性,我们再进一步进行改进,代码如下:
Function.prototype.method = function(funcName,func){ this.prototype[funcName] = func; }; Function.prototype.inherit = function(parent){ this.prototype = new parent(); this.prototype.constructor = this; }; function Sun5(){} Sun5.inherit(Father); console.log(new Sun5());
Function.prototype.inherit:这一函数能用来实现单父继承。由于inherit方法是在Function的原型中的,所以使得所有的子类都能有原生的使用该inherit方法,只需要传递父类的构造函数即可。
注意:在inherit函数中调用parent 的构造函数,没有给它传递参数。这在原型链中是标准做法。要确保构造函数没有任何参数。
如果父类的构造函数中有参数,那该怎么办呢?可以这样实现,代码如下:
function Father(name,age){ this.name = name; this.age = age; this.setName = function(str){this.name=str}; this.getName = function(){return this.name;}; } Father.prototype.setAge = function(age){this.age = age;}; Father.prototype.getAge = function(){return this.age;}; console.log(new Father()); Function.prototype.method = function(funcName,func){ this.prototype[funcName] = func; }; Function.prototype.inherit = function(parent){ this.prototype = new parent(); this.prototype.constructor = this; }; function Sun6(name,age){ Father.call(this,name,age); } Sun6.inherit(Father); console.log(new Sun6("姓名",20));
这里通过call与prototype的共同使用才实现了继承。
参考:
http://www.ruanyifeng.com/blog/2010/05/object-oriented_javascript_inheritance.html
http://www.w3school.com.cn/js/pro_js_inheritance_implementing.asp