A-A+

javascript 继承与原型继承用法详解

2016年10月17日 web前端设计 暂无评论 阅读 7 views 次

本文章来给大家总结一下在javascript 继承与原型继承用法,有需要了解继承与原型继承用法的朋友可进入参考参考JavaScript是基于原型的面向对象语言,没有类的概念,我们先来说说原型prototype,每个对象都有原型,原型是一种对象,修改对象的原型,可以影响所有由本对象派生的对象,但是如果仅仅修改本对象,并不会影响已经创建的实例的原型,因为每个对象和原型都有一个原型,对象的原型指向对象的父原型,而父原型又指向父原型的父原型,这种通过原型层层连接起来的关系称为原型链,这条链的末端一般总是默认的对象原型.

JavaScript 是基于原型的面向对象语言。也就是说,每个实例对象都具有一个原型。对象从该原型中继承属性和方法。

1、构造函数

利用构造函数,可以简单地创建对象,构造函数内的 this 关键字指向实例对象本身,代码如下:

function People(name)
{
this.name = name;
}

使用 new 运算符和构造函数创建实例对象,代码如下:

var people = new People('小明');
console.log(people.name); //小明

但如果创建了两个实例,这两个实例之间无法直接共享属性和方法,代码如下:

var people1 = new People('小明');

var people2 = new People('小王');

people1.sex = 'male';

console.log(people2.sex); //undefined

也就是说对象一旦被实例化,其属性方法都独立存在,对某个属性的修改不会影响到其他实例。

2、Prototype

于是就有了 prototype 属性,这个属性是在生成实例对象时自动创建的。它本身又是一个对象,拥有能够在实例间共享的属性和方法。而实例本身的属性和方法,则包含在构造函数中。换句话说,构造函数内部的属性和方法,在经过实例化后都成为了本地的属性和方法,而原型(prototype)中的属性和方法在实例中只是一种引用,因此能够被多个实例共享。

还是刚才那个构造函数,现在为它增加 prototype 属性,代码如下:

People.prototype.sex = 'female'; //或者写成

People.prototype = {sex: 'female'};

console.log(people1.sex); //male

console.log(people2.sex); //female

People 构造函数的 prototype 属性参数会直接影响到 people1 和 people2 两个实例,但为什么 people1.sex 输出 male 呢?这是由于在 JavaScript 中,原型关系以递归形式存在。对象的原型也是一个对象,而原型的本身也可能具有一个原型。原型的最高层级是全局的 Object 对象。

这就是说,一旦 people1.sex 被设置为 male 后,它在原型中对应的值就无法被暴露出来。假如 people1.sex 本身没有值,才会从构造函数的 prototype 属性中读取,以此类推一级一级向上查找,直到 Object 对象。

注:使用 “null” 给对象赋值,可以销毁自定义对象,释放内存资源,原型中读的是从原型链上读,写是往自己里面写。

一个继承的小例子,代码如下:

  1. //继承  
  2. function Person(name,sex)  
  3. {  
  4. this.name=name;  
  5. this.sex=sex;  
  6. }  
  7. Person.prototype.sayName=function()  
  8. {  
  9. alert(this.name);  
  10. }  
  11. Person.prototype.saySex=function()  
  12. {  
  13. alert(this.sex);  
  14. }  
  15. function Worker(name,sex,job)  
  16. {  
  17. //继承person类   
  18. Person.call(this,name,sex) //这里的this指的是Worker类的实例,如下面的'W' ,把W传入Person构造函数,这时W伪装成Person构造函数里的this  
  19. this.job=job;  
  20. }  
  21. //Worker.prototype=Person.prototype;//如果这样负值原型,子类的sayJob方法Person父类也会有sayJob方法,因为是引用传递  
  22. //改成如下方式则子类不会影响父类:  
  23. for(var i in Person.prototype)  
  24. {  
  25. Worker.prototype[i]=Person.prototype[i];  
  26. }  
  27. Worker.prototype.sayJob=function()  
  28. {  
  29. alert(this.job);  
  30. }  
  31. var p=new Person('lisi','男');  
  32. //alert(p.sayJob);  
  33. var w=new Worker('zhangsan','男','打酱油的');  
  34. w.sayName();//xiariboke.com  
  35. w.saySex();  
  36. w.sayJob();  

为了表达更明确,我们再创建一个Pig类出来,并且继承Animal类。怎么创建我就不说了。创建完的代码应该是像现在这样子,代码如下:

  1. function Dog(){};  
  2. Dog.prototype = new Animal("Henry");  
  3. function Pig(){};  
  4. Pig.prototype = new Animal("Coco");  
  5. var dog = new Dog();  
  6. dog.jump();  
  7. dog.eat();  
  8. var pig = new Pig();  
  9. pig.jump();  
  10. pig.eat();  

  
运行之后,因为继承了Animal类的原因,结果肯定又是“XX is jumping...”,“XX is eatting...”了,那我们要实现的,就是进行方法的重写。我们可以有下面的方式实现方法的重写,代码如下:

  1. function Dog(){};//创建dog子类  
  2. Dog.prototype = new Animal("Henry");  
  3. //重写dog的方法  
  4. Dog.prototype.jump = function(){  
  5.     alert("Hi, this is " + this.name + ", I'm jumping...")  
  6. };  
  7. Dog.prototype.eat = function(){  
  8.     alert("Henry is eatting a bone now.");      
  9. };  
  10. function Pig(){};//创建pig子类  
  11. Pig.prototype = new Animal("Coco");  
  12. //重写pig的方法  
  13. Pig.prototype.jump = function(){  
  14.     alert("I'm sorry. " + this.name + " can not jump.");  
  15. };  
  16. Pig.prototype.eat = function(){  
  17.     alert("Hi, I'm " + this.name + ", I'm eatting something delicious.");  
  18. }  
  19. var dog = new Dog();  
  20. dog.jump();  
  21. dog.eat();  
  22. var pig = new Pig();  
  23. pig.jump();  
  24. pig.eat();  

运行一下,是不是实现了对方法的重写呢??

6、那么,假如我实例化一只dog之后,我想单独为这只dog添加属性和方法,怎么做呢?看下面

  1. var dog = new Dog();  
  2. //添加属性和方法  
  3. dog.type = "Doberman Pinscher";  
  4. dog.shout = function(){  
  5.     alert("I'm a " + this.type + ".");  
  6. }  
  7. dog.jump();  
  8. dog.eat();  
  9. //调用新的方法  
  10. dog.shout();  

好了,这篇文章就写到这里了,相信初学者对于类的创建与继承应该有一定的了解了,如果有什么问题,可以留言啊.

标签:

给我留言