javascript 继承

  javascript ES5 并没有所谓class 类,所以自然不能像c++,Java 那样子类继承父类,但是javascript还是可以实现继承的。

  主要的继承方式分为构造函数继承和非构造函数继承

一、构造函数继承

构造一个原型函数,将需要定义的属性方法,通过指定 this 指向赋值;通过 new 方法实例化对象

1 function Person(name,sex,age,interest){
2   this.name=name;
3  this.age=age;
4  this.sex=sex;
5  this.interest=interest;
6  }

为了在实例化对象后,每个对象相同的属性方法占用内存,我们将对象相同不变的方法和属性放在对象的prototype上,这样子每个实例相同部分都指向同一个内存地址

 1 Person.prototype.action ="walk" ;
 2  Person.prototype.mouth = "eat and speak";
 3 
 4 var Mary =new Person("mary","woman","20","shopping");
 5  var Tom = new Person("tom","man","23","play baseketball");
 6  
 7  "eat and speak"
 8  Mary.action
 9  //"walk"
10  Tom.mouth
11  //"eat and speak"

如果觉得要写很多prototype.什么很麻烦,也可以直接另外写一个"父类"方法函数,将不变的东西放在里面,然后"子类"的原型函数中进行函数绑定,例如在Person 中加 :

primaryPerson.apply(this, arguments);   //primaryPerson 为"父类" 函数;

二、非构造函数方法

浅拷贝

 1 var Person ={
 2 
 3 action :'walk';
 4 
 5 }
 6 
 7 var Man ={
 8 name :"bentos",
 9 age : "20",
10 bithPlace :shantou"
11 }

 

 除了使用"prototype链"以外,还有另一种思路:把父对象的属性,全部拷贝给子对象,也能实现继承。

1 function extendCopy(p) {
2     var c = {};
3     for (var i in p) { 
4       c[i] = p[i];
5     }
6     c.uber = p;
7     return c;
8   }

 

使用的时候,这样写

1 var Man= extendCopy(Person);
2 console.log(Person.action);
3 //walk

 

但是,这样的拷贝有一个问题。那就是,如果父对象的属性等于数组或另一个对象,那么实际上,子对象获得的只是一个内存地址,而不是真正拷贝,因此存在父对象被篡改的可能。

现在给Person添加一个"脸"属性,它的值是一个数组。

 

1 Person.face = ['mouth','eye','nose'];

 

 

 

通过extendCopy()函数,Man继承了Person。

 

1 var Man = extendCopy(Person);

 

然后,我们为Man的"face"添加一个属性:

1 Man.face.push('smalleye');

 

 

发生了什么,Person 的属性也被改变了

 

1 Person.face
2 ["mouth", "eye", "nose", "smalleye"]

 

所以,extendCopy()只是拷贝基本类型的数据,我们把这种拷贝叫做"浅拷贝"。这是早期jQuery实现继承的方式。

深拷贝

所谓"深拷贝",就是能够实现真正意义上的数组和对象的拷贝。它的实现并不难,只要递归调用"浅拷贝"就行了。

 

 

 1 function deepCopy(p, c) {
 2     var c = c || {};
 3     for (var i in p) {
 4       if (typeof p[i] === 'object') {
 5         c[i] = (p[i].constructor === Array) ? [] : {};
 6         deepCopy(p[i], c[i]);
 7       } else {
 8          c[i] = p[i];
 9       }
10     }
11     return c;
12   }

 

 

 

使用时这样写

 

var Person= deepCopy(Man);

 

现在,给父对象加一个属性,值为数组。然后,在子对象上修改这个属性,这时,父对象不会受到影响了。

 

posted @ 2016-08-13 23:17  bentos  阅读(172)  评论(0编辑  收藏  举报