首页 > 代码库 > javascript面向对象程序设计——继承初步(by vczero)
javascript面向对象程序设计——继承初步(by vczero)
上一篇说了javascript的封装,没有刻意去说javascript的“共有函数”、“私有函数”,因为个人觉得这只是作用域的问题,我们不能刻意的模仿强类型语言(C++/JAVA)而去编写代码。尊重每一门语言的特性才是最为重要的。
一、基于prototype原型的继承
1 var Person = function(name, age){ 2 this.name = name; 3 this.age = age; 4 } 5 6 Person.prototype = { 7 addUser: function(){ 8 console.log(‘用户:‘ + this.name + ‘已添加‘); 9 },10 11 getName: function(){12 return this.name;13 }14 }15 16 Person.getUser = function(user){17 console.log(user.name + ‘已经找到‘);18 }19 20 var p = new Person(‘山鬼谣‘, 30);21 console.log(p.name);//山鬼谣22 p.addUser();//用户:山鬼谣已经添加23 Person.getUser(p); //山鬼谣已经找到
这时,我们看到《侠岚》中的游不动(人名)也出现了,但是游不动是最为基本的侠岚(四象侠岚),因此游不动具有自己的个性特征。因此,我们需要构建四象侠岚的类SiXiang,但是四象侠岚又具备最基本的Person特性,因此继承于Person。
1 var Sixiang = function(name, age, tech){ 2 this.name = name; 3 this.age = age; 4 this.tech = tech; 5 } 6 7 Sixiang.prototype = new Person(); 8 Sixiang.prototype.showTech = function(){ 9 console.log(‘我的技能是:‘ + this.tech);10 }11 12 var youbudong = new Sixiang(‘游不动‘, 18, ‘土‘);13 console.log(youbudong.name);//游不动14 youbudong.addUser();//用户:游不动已经添加15 console.log(youbudong.getName());//游不动16 youbudong.showTech();//我的技能是:土17 //静态方法是不能被继承的,因为Sixiang.prototype接收的是一个实例18 //youbudong.getUser(youbudong); //has no method getUser
我们可以看到通过原型的继承,因为是new一个实例赋给了子类的prototype,因此,子类子包含父类实例的方法,而不含类方法(静态方法)。如果子类中定义了与父类中原型一样的方法,将会覆盖父类的方法如,新增Sixiang.prototype.getName方法:
1 var Sixiang = function(name, age, tech){ 2 this.name = name; 3 this.age = age; 4 this.tech = tech; 5 } 6 7 Sixiang.prototype = new Person(); 8 Sixiang.prototype.showTech = function(){ 9 console.log(‘我的技能是:‘ + this.tech);10 }11 12 Sixiang.prototype.getName = function(){13 return ‘四象侠岚的getName方法‘;14 }15 16 var youbudong = new Sixiang(‘游不动‘, 18, ‘土‘);17 console.log(youbudong.name);//游不动18 youbudong.addUser();//用户:游不动已经添加19 console.log(youbudong.getName());//四象侠岚的getName方法20 youbudong.showTech();//我的技能是:土21 //静态方法是不能被继承的,因为Sixiang.prototype接收的是一个实例22 //youbudong.getUser(youbudong); //has no method getUser
二、构造函数指向问题
我们可以测试下以下代码,发现Sixiang的构造函数指向有问题。
console.log(youbudong.constructor === Sixiang);//falseconsole.log(youbudong.constructor === Person);//false
这不对啊,为什么既不是父类的构造函数又不是子类的呢。将子类整理以下,我们将代码拷贝到chrome的console中看看,发现:
1 var Sixiang = function(name, age, tech){ 2 this.name = name; 3 this.age = age; 4 this.tech = tech; 5 } 6 7 Sixiang.prototype = new Person(); 8 Sixiang.prototype.showTech = function(){ 9 console.log(‘我的技能是:‘ + this.tech);10 }11 12 var youbudong = new Sixiang(‘游不动‘, 18, ‘土‘);13 console.log(youbudong.name);//游不动14 youbudong.addUser();//用户:游不动已经添加15 console.log(youbudong.getName());//四象侠岚的getName方法16 youbudong.showTech();//我的技能是:土17 console.log(youbudong);
我们在var youbudong = new Sixiang(‘游不动‘, 18, ‘土‘);前添加Sixiang.prototype.constructor = Sixiang;我们再到chrome看。
1 var Sixiang = function(name, age, tech){ 2 this.name = name; 3 this.age = age; 4 this.tech = tech; 5 } 6 7 Sixiang.prototype = new Person(); 8 Sixiang.prototype.showTech = function(){ 9 console.log(‘我的技能是:‘ + this.tech);10 }11 Sixiang.prototype.constructor = Sixiang;12 var youbudong = new Sixiang(‘游不动‘, 18, ‘土‘);13 console.log(youbudong.name);//游不动14 youbudong.addUser();//用户:游不动已经添加15 console.log(youbudong.getName());//四象侠岚的getName方法16 youbudong.showTech();//我的技能是:土17 console.log(youbudong);18 console.log(youbudong.constructor === Sixiang);//true
这样,构造函数的指向问题得以修正。下一篇,重点介绍原型链和封装类的继承。
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。