继承有类式继承,构造函数继承人,组合继承

1:类式继承:

// 声明父类

function Parent(){ this.parentValue = true; }

// 为父类添加共有方法

Parent.prototype.getParentValue = function(){ return this.parentValue; }

// 声明子类

function Child(){ this.childValue = false; }

// 继承父类

Child.prototype = new Parent();

// 为子类添加共有方法

Child.prototype.getChildValue = function(){ return this.childValue; }

类的原型对象的作用是为类的原型添加共有属性和方法,

但类必须通过原型prototype来访问这些属性和方法。

当实例化一个父类时,

新建对象复制了父类构造函数内的属性和方法,并且将原型__proto__指向了父类的原型对象,

这样就拥有了父类原型对象上的属性和方法,新建对象可以直接访问父类原型对象的属性和方法,

接着将这个新建的对象赋值给子类的原型,那么子类的原型就可以访问父类的原型属性和方法。

将这个对象赋值给子类的原型,那么这个子类就可以访问父类原型上的属性和方法,并且可以访问从父类构造函数中复制的属性和方法。我们可以来测试一下:

var child = new Child();

console.log(child.getParentValue()); // true

console.log(child.getChildValue()); // false

console.log(child instanceof Parent); // true

console.log(child instanceof Child); // true

console.log(Child instanceof Parent); // false

但这种继承方式有2个缺点:

  • 由于子类是通过其原型prototype对父类实例化,如果父类中的共有属性是引用类型,会被所有实例所共享,一个子类的实例修改了该属性会直接影响到所有实例。例如:

    function Parent(){
    this.values = [‘A‘,‘B‘,‘C‘];
    }
    function Child(){}
    Child.prototype = new Parent();
    var child1 = new Child();
    var child2 = new Child();
    console.log(child2.values);    // ["A","B","C"]
    child1.values.push(‘D‘);
    console.log(child2.values);    // ["A","B","C","D"]
  • 创建父类实例时,是无法向父类传递参数的,也就是无法对父类构造函数内的属性进行初始化。例如这种错误的继承方式:
    function Parent(name){
    this.name = name;
    }
    function Child(){}
    Child.prototype = new Parent(‘name‘);    // 错误

构造函数继承

// 声明父类
function Parent(name){
    this.name = name;
    this.values = [‘A‘,‘B‘,‘C‘];
}
Parent.prototype.showName = function(){
    console.log(this.name);
}
// 声明子类
function Child(name){
    Parent.call(this,name);
}
var child1 = new Child(‘one‘);
var child2 = new Child(‘two‘);
child1.values.push(‘D‘);
console.log(child1.name);   // one
console.log(child1.values); // ["A","B","C","D"]
console.log(child2.name);   // two
console.log(child2.values); // ["A","B","C"]
child1.showName();          // TypeError

语句Parent.call(this,name);是构造函数继承的精华,call方法可以更改函数的作用环境,在子类中执行该方法相当于将子类的变量在父类中执行一遍,此时父类方法中的this属性指的是子类中的this,由于父类中是给this绑定属性的,所以子类也就继承了父类的属性和方法。构造函数继承并没有涉及原型prototype,所以父类的原型方法不会被子类继承,子类的每个实例会单独拥有一份父类的属性方法而不能共用,如果想被子类继承就必须放在构造函数中,要实现这样的效果可以采用组合继承的方式。

组合继承

类式继承是通过子类的原型prototype对父类实例化来实现的,构造函数继承是通过在子类的构造函数作用环境中执行一次父类的构造函数来实现的,而组合继承则同时做到这两点。

// 声明父类
function Parent(name){
    this.name = name;
    this.values = [‘A‘,‘B‘,‘C‘];
}
Parent.prototype.getName = function(){
    console.log(this.name);
}
// 声明子类
function Child(name,id){
    Parent.call(this, name);
    this.id = id;
}
Child.prototype = new Parent();
Child.prototype.getId = function(){
    console.log(this.id);
}

var child1 = new Child(‘child1‘, 1);
child1.values.push(‘D‘);
console.log(child1.values); // ["A", "B", "C", "D"]
child1.getName();           // child1
child1.getId();             // 1

var child2 = new Child(‘child2‘, 2);
console.log(child2.values);    // ["A", "B", "C"]
child2.getName();              // child2
child2.getId();                // 2

子类的实例中更改父类继承下来的引用类型属性,不会影响到其它实例,并且子类实例化过程中又能将参数传递到父类的构造函数中。

多态

多态就是同一个方法多种调用方式,JavaScript可以通过对传入的参数列表arguments进行判断来实现多种调用方式。例如:

function Add(){
    // 无参数
    function zero(){
        return 0;
    }
    // 一个参数
    function one(num){
        return num;
    }
    // 两个参数
    function two(num1, num2){
        return num1 + num2;
    }

    this.add = function(){
        // 获取参数列表及参数个数
        var arg = arguments,
            len = arg.length;
        switch(len){
            case 0:
                return zero();
            case 1:
                return one(arg[0]);
            case 2:
                return two(arg[0], arg[1]);
        }
    }
}

var A = new Add();
console.log(A.add());       // 0
console.log(A.add(1));      // 1
console.log(A.add(1,2));    // 3

当调用add进行运算时,会根据参数列表的不同做相应的运算,这就是JavaScript的多态实现方式。

总结

面向对象设计方法的应用解决了传统结构化开发方法中客观世界描述工具与软件结构的不一致性问题,缩短了开发周期,解决了从分析和设计到软件模块结构之间多次转换映射的繁杂过程,是一种高效率的软件开发方式,特别是在多人协作开发的情况下,可以提高代码的可复用性和维护性,使开发更有效率。

时间: 2024-10-09 19:20:29

继承有类式继承,构造函数继承人,组合继承的相关文章

JS原型继承和类式继承

类式继承(构造函数) JS中其实是没有类的概念的,所谓的类也是模拟出来的.特别是当我们是用new 关键字的时候,就使得"类"的概念就越像其他语言中的类了.类式继承是在函数对象内调用父类的构造函数,使得自身获得父类的方法和属性.call和apply方法为类式继承提供了支持.通过改变this的作用环境,使得子类本身具有父类的各种属性. JavaScript var father = function() { this.age = 52; this.say = function() { al

原型继承和类式继承

类式继承(构造函数) JS中其实是没有类的概念的,所谓的类也是模拟出来的.特别是当我们是用new 关键字的时候,就使得“类”的概念就越像其他语言中的类了.类式继承是在函数对象内调用父类的构造函数,使得自身获得父类的方法和属性.call和apply方法为类式继承提供了支持.通过改变this的作用环境,使得子类本身具有父类的各种属性. var father = function() { this.age = 52; this.say = function() { alert('hello i am

js原生设计模式——2面向对象编程之继承—new类式继承

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>classInherit</title>    <script type="text/javascript">    //声明父类    function superClass(){        this.name

JavaScript各种继承方式(六):寄生组合继承

一 原理 用寄生继承来改造组合继承. function Fruit(name){ this.name = name; } Fruit.prototype.eat = function(){ console.log('eat'); } function Mango(name,level){ Fruit.call(this,name); this.level = level; } function create(obj){ let instance = Object.create(obj); //

js中继承的实现,原型链的知识点归纳,借用构造函数,组合继承(伪经典继承)

博客搬迁,给你带来的不便,敬请谅解! http://www.suanliutudousi.com/2017/10/31/js%e4%b8%ad%e7%bb%a7%e6%89%bf%e7%9a%84%e5%ae%9e%e7%8e%b0%ef%bc%8c%e5%8e%9f%e5%9e%8b%e9%93%be%e7%9a%84%e7%9f%a5%e8%af%86%e7%82%b9%e5%bd%92%e7%ba%b3%ef%bc%8c%e5%80%9f%e7%94%a8%e6%9e%84%e9%80%a

Javascript继承(暂略去中转函数、组合继承和寄生继承)

继承,在JS中通过原型链实现.如: function Box(){ this.name="Lee"; } function Desk(){ this.age=100; } //通过原型链继承,超类实例化的对象赋值给子类的原型 Desk.prototype=new Box(); var desk=new Desk(); alert(desk.name); 这样,Desk的原型得到了Box的实例对象+对象信息,形成了原型链. 继承遵循就近原则,子类继承父类就近的属性.如: function

282 继承模式:原型链继承 : 得到方法,借用构造函数 : 得到属性,组合,new一个对象背后做了些什么

1.原型链继承 : 得到方法 function Parent(){} Parent.prototype.test = function(){}; function Child(){} Child.prototype = new Parent(); // 子类型的原型指向父类型实例 Child.prototype.constructor = Child var child = new Child(); //有test() <!DOCTYPE html> <html lang="e

Javascript之对象组合继承

感悟: 最近看了一些关于Javascript对象继承的知识,发现自己之前虽然看了一些书,但是很多知识都忘了.虽然很多东西都忘了,但再次看的过程中对这些东西不会再向刚接触时那么陌生,而且理解起来也比之前顺畅和透彻多了. 充分说明:多看书是有意义的. ————————————————————————————————————————————————————————————————————————————————————————————碎碎念 关于对象之间的继承,在Javascript中主要是通过原型对

【ES6】更易于继承的类语法

和其它面向对象编程语言一样,ES6 正式定义了 class 类以及 extend 继承语法糖,并且支持静态.派生.抽象.迭代.单例等,而且根据 ES6 的新特性衍生出很多有趣的用法. 一.类的基本定义 基本所有面向对象的语言都支持类的封装与继承,那什么是类? 类是面向对象程序设计的基础,包含数据封装.数据操作以及传递消息的函数.类的实例称为对象. ES5 之前通过函数来模拟类的实现如下: // 构造函数 function Person(name) { this.name = name; } //