上一篇说了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);//false
console.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
这样,构造函数的指向问题得以修正。下一篇,重点介绍原型链和封装类的继承。
Javascript面向对象程序设计——继承初步(by vczero),,
Javascript面向对象程序设计——继承初步(by vczero)