zoukankan      html  css  js  c++  java
  • js继承

    ---恢复内容开始---

    JS继承的概念

    js里常用的如下两种继承方式: 通过原型链方式实现继承(对象间的继承)、 类式继承(构造函数间的继承)

    由于js不像Java那样是真正面向对象的语言,js是基于对象的,它没有类的概念。所以,要想实现继承,可以用js的原型prototype机制或者用apply和call方法去实现

    原型链

    构造函数、原型、实例的关系:

    每个构造函数都有一个原型对象(prototype),原型对象都包含一个指向构造函数的指针(constructor),而实例都包含一个指向原型对象的内部指针(__proto__)。

    假如我们让原型对象等于另一个类型的实例,结果会怎么样呢?显然,此时的原型对象将包含一个指向另一个原型的指针,相应地,另一个原型中也包含一个指向一个构造函数的指针。假如另一个原型又是另一个类型的实例,那么上述关系依然成立,如此层层递进,就构成了实例与原型的链条。这就是所谓原型链的基本概念。

    (每个对象都有一个内部属性__proto__属性,属性的值可以是一个对象,也可以是null.如果它的值是一个对象,则这个对象也一定有自己的原型.这样就形成了一条线性的链,我们称之为原型链)

    通过原型链方式实现继承

    实现的本质是重写原型对象,代之以一个新类型的实例。 换句话说,原来存在于Parent的实例中的所有属性和方法,现在也存在于Son.prototype中了。在确定了继承关系之后,我们给Son.prototype添加了一个新的方法。 要注意,obj.constructor现在指向的是Parent,这是因为原来Son.prototype中的constructro被重写了的缘故。

    通过原型链方式实现继承

    为了让子类继承父类的属性(也包括方法),首先需要定义一个构造函数。然后,将父类的新实例赋值给构造函数的原型。

    代码如下:

    <script>

    function Parent(){ this.name = 'mike'; }

    function Child(){ this.age = 12; }

    Child.prototype = new Parent(); //Child继承Parent,通过原型,形成链条

    var test = new Child();

    alert(test.age);

    alert(test.name); //得到被继承的属性 //继续原型链继承

    function Brother(){ //brother构造 this.weight = 60; }

    Brother.prototype = new Child();//继续原型链继承

    var brother = new Brother();

    alert(brother.name);//继承了Parent和Child,弹出mike

    alert(brother.age);//弹出12

    </script>

     确定原型和实例的关系

    可以通过两种方式来确定原型和实例之间的关系。 操作符instanceof和isPrototypeof()方法:

    instanceof 只要用这个操作符来测试实例与原型链中出现过的构造函数,结果就会返回true.

    alert(obj instanceof Object) //true

    alert(obj instanceof Son); //true

    alert(obj instanceof Parent); //true

    isPrototypeOf() 只要原型链中出现过的原型,都可以说是该原型链所派生的实例的原型,因此也会返回true;

    .alert(Object.prototype.isPrototypeOf(obj)) //true

    alert(Son.prototype.isPrototypeOf(obj)); //true

    alert(Parent.prototype.isPrototypeOf(obj)); //true

    使用原型链继承的问题

    在js中,被继承的函数称为超类型(父类,基类也行),继承的函数称为子类型(子类,派生类)。 在创建子类型的实例时,不能向超类型的构造函数中传递参数。 实践中很少会单独使用原型链

    借用构造函数(类式继承)

    <script>

    function Parent(age){

    this.name = ['mike','jack','smith']; t

    his.age = age;

    }

    function Child(age){

    Parent.call(this,age); //Parent.apply(this,age);

    }

    var test = new Child(21);

    alert(test.age);//21

    alert(test.name);//mike,jack,smith test.name.push('bill');

    alert(test.name);//mike,jack,smith,bill

    </script>

    组合继承

    组合式继承是比较常用的一种继承方法,其背后的思路是: 使用原型链实现对原型属性和方法的继承,而通过借用构造函数来实现对实例属性的继承。这样,既通过在原型上定义方法实现了函数复用,又保证每个实例都有它自己的属性。

    <script>

    function Parent(age){

    this.name = ['mike','jack','smith'];

    this.age = age; }

    Parent.prototype.run = function () {

    return this.name + ' are both' + this.age;

    };

    function Child(age){

    Parent.call(this,age);//对象冒充,给超类型传参

    }

    Child.prototype = new Parent();//原型链继承

    var test = new Child(21);//写new Parent(21)也行 alert(test.run());//mike,jack,smith are both21

    </script>

    ---恢复内容结束---

  • 相关阅读:
    剑指offer
    NET 的 ELK 监控方案
    SSM 框架整合
    搭建ELK 6
    NETCOREAPI 跨域处理
    修改数据库端口为51433
    修改ftp端口为50021
    文件每日备份批处理
    修改3389为53389
    批处理实现自动删除过期文件的定期操作
  • 原文地址:https://www.cnblogs.com/weiyz/p/7158586.html
Copyright © 2011-2022 走看看