整理js继承

实现继承的方法:

一,原型链:利用原型让一个引用类型继承另一个引用类型的属性和方法

function SuperType(){
    this.property=true;
}

SuperType.prototype.getSuperValue=function(){
    return this.property;
};
function SubType(){

    this.subproperty=false;
}
//继承了SuperType
SubType.prototype=new SuperType();
SubType.prototype.getSubValue=function(){
      return this.subproperty;

}
 var instance=new SubType();
 alert(instance.getSuperValue());  //true

注意问题:

a:所有引用类型默认都继承了Object,也是通过原型链实现的,所有函数的默认原型都是Object的实例。

alert(instance instanceof Object);  //true

b:确定原型和实例之间的关系,可以用instanceof操作符和isPrototypeOf()方法。

实例与原型链中出现过的构造函数都会返回true。

alert(instance instanceof SubType);  //true 

原型链中出现过的原型,都可以说是原型链派生的实例的原型,返回true。

alert(SubType.prototype.isPrototypeOf(instance));  //true

c:给原型添加方法的代码一定要放在替换原型的语句之后。

d:通过原型链实现继承时不能使用对象字面量创建原型的方法,这样会重写原型链,之前的原型链被切断,SubType和SuperType之间没有关系了。

e:原型链的问题:每个实例都会共享属性,子类型不能向超类型中传参

优点:实例的方法可以共享

缺点:所有实例的属性共享

二,借用构造函数:在子类的构造函数内部调用超类型构造函数

function SuperType(){
    this.colors=["red","blue","green"];//该数组就是引用类型值
}
function SubType(){
   //继承了SuperType
   SuperType.call(this);//SuperType.call(this)的意思就是使用SuperType 对象代替this对象,那么Subtype中不就有SuperType的所有属性和方法了,instance1对象就能够直接调用SuperType的方法以及属性了
}
var instance1=new SubType();
instance1.colors.push("black");
alert(instance1.colors);  //red,blue,green,black

var instance2=new SubType();
alert(instance2.colors);//red,blue,green 

a:可以传递参数

b:借用构造函数问题:方法都在构造函数中定义,因此所有函数无法复用

优点:解决了原型链实现继承属性共享的问题,可以传递参数

缺点:函数无法复用,每个实例的方法都不相同

三,组合继承:将原型链和借用构造函数的技术组合到一块,扬长补短,思想:使用原型链对原型属性和方法的继承,使用借用构造函数实现对实例属性的继承。

function SuperType(name){
            this.colors=["red","green","blue"];
            this.name=name;
        }
        //用原生链的方式将方法写在外面,让每个实例使用相同的方法
        SuperType.prototype.sayName=function(){
            alert(this.name);
        };
        function SubType(name,age){
            //第二次调用SuperType()
            SuperType.call(this,name);  //让每个实例分别拥有自己的属性
            this.age=age;
        }
        //继承方法
        SubType.prototype=new SuperType();   //第一次调用SuperType()
        //弥补因重写原型而失去的默认的constructor属性
        SubType.prototype.constructor=SubType;
        SubType.prototype.sayAge=function(){
            alert(this.age);
        };

        var instance1=new SubType("jane",29);
        instance1.colors.push("black");
        alert(instance1.colors); //red,green,blue,black
        instance1.sayName();  //jane
        instance1.sayAge();  //29

        var instance2=new SubType("tom",30);
        alert(instance2.colors);//red,green,blue
        instance2.sayName();  //tom
        instance2.sayAge();  //30

        alert(instance1.sayName==instance2.sayName);  //true
        alert(SubType.prototype.constructor==SubType);//true

优点:最常用的继承模式,解决了借用构造函数,函数不能复用的问题,以及原型链属性共享,以及不能传参的问题

缺点:如代码中所说,调用了两次超类型构造函数,如果删除instance2的colors属性,依然会返回red,green,blue,这样就无法删除colors属性

delete instance2.colors;
alert(instance2.colors);//red,green,blue

四,原型式继承:基于已有的对象创建新对象

Object.create()方法实现原型式继承:

//传入一个参数的情况下,对象名
  var person={
       name:"jane",
       friends:["tom","nike","van"]
   };

   var anotherPerson=Object.create(person);
   anotherPerson.name="greg";
   anotherPerson.friends.push("rob");

   var yetAnotherPerson=Object.create(person);
   yetAnotherPerson.name="linda";
   yetAnotherPerson.friends.push("barbie");

   alert(person.friends); //tom,nike,van,rob,barbie*
//Object.create()方法传入两个参数,第一个参数,对象名,第二个参数:属性都是通过自己的描述符定义的。
var person={
    name:"jane",
    friends:["tom","nike","van"]
};
var anotherPerson=Object.create(person,
    {    //以这种方式指定的任何属性都会覆盖原型对象上的同名属性。
        name:{
        value:"greg"
      }
    }
); 

alert(anotherPerson.name); //greg    

优点:不用再创建自定义的类型了

缺点:引用类型值的属性都会共享相应的值

五,寄生式继承:封装继承过程的函数

//createAnother函数接收了一个参数,也就是将要作为新对象基础的对象。
function createAnother(original){
    //把original对象传递给Object函数,将返回的结果赋给clone
    var clone=Object(original);
    //再为clone对象添加一个方法
    clone.sayHi=function(){
      alert("hi");
    };
    return clone;//返回这个对象
}

var person={
    name:"jane",
    friends:["tom","nike","van"]
};

var anotherPerson=createAnother(person);
anotherPerson.sayHi();//hi  anotherPerson具有Person不具有的方法sayHi()

优点:为对象添加函数

缺点:函数无法复用

六,寄生组合式继承:使用寄生式继承超类型的原型,再将结果返回给子类型的原型。

function inheritPrototype(SubType,SuperType){
            var prototype=Object(SuperType.prototype);//创建对象
            prototype.constructor=SubType;  //弥补因重写原型而失去的默认的constructor属性
            SubType.prototype=prototype;//指定对象
        }
function SuperType(name){
            this.name=name;
            this.colors=["red","green","blue"];
        }
 SuperType.prototype.sayName=function(){
            alert(this.name);
        };
 function SubType(name,age){
            SuperType.call(this,name);
            this.age = age;
        }

 inheritPrototype(SubType,SuperType);

 SubType.prototype.sayAge=function(){
            alert(this.age);
        };

 var instence=new SubType("jane",29);
 instence.sayName();
 instence.sayAge();

优点:解决了组合继承的两次调用超类型构造函数问题

时间: 2024-11-09 02:55:15

整理js继承的相关文章

js继承的常用方式

写在前面的话:这篇博客不适合对面向对象一无所知的人,如果你连_proto_.prototype...都不是很了解的话,建议还是先去了解一下JavaScript面向对象的基础知识,毕竟胖子不是一口吃成的. 我们都知道面向对象语言的三大特征:继承.封装.多态,但JavaScript不是真正的面向对象,它只是基于面向对象,所以会有自己独特的地方.这里就说说JavaScript的继承是如何实现的. 学习过Java和c++的都知道,它们的继承通过类实现,但JavaScript没有类这个概念,那它通过什么机

JS继承的实现方式

前言 JS作为面向对象的弱类型语言,继承也是其非常强大的特性之一.那么如何在JS中实现继承呢?让我们拭目以待. JS继承的实现方式 既然要实现继承,那么首先我们得有一个父类,代码如下: // 定义一个动物类 function Animal (name) { // 属性 this.name = name || 'Animal'; // 实例方法 this.sleep = function(){ console.log(this.name + '正在睡觉!'); } } // 原型方法 Animal

js继承的实现

js继承有5种实现方式: 1.继承第一种方式:对象冒充   function Parent(username){     this.username = username;     this.hello = function(){       alert(this.username);     }   }   function Child(username,password){     //通过以下3行实现将Parent的属性和方法追加到Child中,从而实现继承     //第一步:this.

js继承有5种实现方式

js继承有5种实现方式:1.继承第一种方式:对象冒充  function Parent(username){    this.username = username;    this.hello = function(){      alert(this.username);    }  }  function Child(username,password){    //通过以下3行实现将Parent的属性和方法追加到Child中,从而实现继承    //第一步:this.method是作为一

JS继承——原型的应用

前面我们知道JS是基于对象编程的一种脚本语言,在JS本着一切皆对象的原则,对象之间也涉及到了继承,不过这里的继承与我们以往学习过的继承有所不同,它运用的是对象的原型,来构造一个原型链来实现对超类对象的继承. 1.如何实现对象继承 function Box() { //Box 构造<span style="font-family:Arial;font-size:18px;">,超类对象</span> this.name = 'Lee'; } Desk.protot

5种JS继承方法

<!DOCTYPE html> <html> <head> <meta charset=" utf-8"> <meta name="author" content="http://www.jb51.net/" /> <title>5种JS继承方法</title> <script type="text/javascript"> //1

JS 继承的方式

JS 继承的方式 1.使用call的方式 2. code如下 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <script type="text/javascript"> //继承的第二种实

js继承之call,apply和prototype随谈

在js中,call,apply和prototype都可以实现对象的继承,下面我们看一个例子: function FatherObj1() { this.sayhello = "I am join"; this.show = function () { alert("I am FatherObj1"); }; this.getall = function () { if (arguments) alert("GetAll:" + arguments

js继承的实现 by DY

js继承有5种实现方式: 1.继承第一种方式:对象冒充   function Parent(username){     this.username = username;     this.hello = function(){       alert(this.username);     }   }   function Child(username,password){     //通过以下3行实现将Parent的属性和方法追加到Child中,从而实现继承     //第一步:this.