ES5继承模式

  果然,感觉有些东西不整理一下还是很容易忘记的,很多时候有需要不断地去复习,感觉JavaScript这门语言总体上不能算是特别难,但是知识点特别杂(坑也特别多...),感觉最好还是能够梳理出一个整体架构出来

  好了,废话不多说,今天大致上总结一下ES5中的继承模式,大致上还是参照《JavaScript高级程序设计》上来的。

  1. 原型模式

     function Person (name, age) {
         this.name = name;
         this.age = age;
     }
     ?
     Person.prototype.sayName = function () {
            return this.name;
     }
        Person.prototype.sayAge = function () {
            return this.age;
        }
     ?
        function Student (name, age, school) {
            this.name = name;
            this.age = age;
            this.school = school;
        }
     ?
        Student.prototype = new Person();
        Student.prototype.saySchool = function () {
            return this.school;
        }
     ?
        let stu = new Student(‘zhang‘, 18, ‘zust‘);
        console.log(stu.getName()); // ‘zhang‘
     ?

   以上的继承方式是比较好理解的,当访问Student实例的sayName()方法时,先遍历实例方法(无匹配),再搜索

   原型对象Person实例(无匹配), 最后搜索Person.prototype对象上,得到sayName()方法。

  1. 借用构造函数

     function Person(name, age){
         this.name = name;
         this.age = age;
     }
     ?
     Person.prototype.sayName = function () {
         return this.name;
     }
     ?
     Person.prototype.sayAge = function () {
         return this.age;
     }
     ?
     function Student(name, age, school){
         Person.call(this, name, age);
         this.school = school;
     }
     ?

    所谓的借用构造函数是借用父类的构造函数来设置自己的属性,进一步避免了代码的重复。

    以上是单纯使用了借用构造函数实现的继承,可以看到在子类中通过重用父类的构造方法为子类设置属性,但是仅仅使用借用构造函数,子类将无法继承父类构造函数原型中的方法。

  2. 组合式继承(原型模式与借用构造函数的组合)
     function Person(name, age){
         this.name = name;
         this.age = age;
     }
     Person.prototype.sayName = function () {
         return this.name;
     }
     Person.prototype.sayAge = function () {
         return this.age;
     }
     ?
     function Student(name, age, school) {
         Person.call(this, name, age);
         this.school = school;
     }
     ?
     Student.prototype = new Person();
     ?

    以上的继承方式是原型模式和借用构造函数模式的组合方式,通过原型链的方式继承父类构造函数原型对象上的方法,使用借用构造函数重用父类构造函数中的代码。相当于是对于原型链继承模式的优化,将父类构造函数中的代码加以重用。

  3. 原型式继承
     let sup = {name: ‘zhang‘, age: 18};
     let extend = function (obj) {
         function F () {};
         F.prototype = obj;
         return new F();
     }
     ?
     let sub = extend(sup);
     console.log(sub.name);

    就以上的继承方式而言,个人感觉与以下实现方式并没有太大区别

     let sup = {name: ‘zhang‘, age: 18};
     let sub = {};
     Object.setPrototypeOf(sub, sup);
     console.log(sub.name);

    在子类对象创建的过程中,所有的父类变量将会被子类共享,尤其是引用类型的变量

     const sup = {name: ‘zhang‘, age: 18, arr: [‘a‘, ‘b‘, ‘c‘]}
     ?
     const extend = function (obj) {
         function F(){};
         F.prototype = obj;
         return new F();
     }
     const a = extend(sup);
     const b = extend(sup);
     console.log(a.arr); // [‘a‘, ‘b‘, ‘c‘]
     b.arr.push(‘d‘);
     console.log(a.arr); // [‘a‘, ‘b‘, ‘c‘, ‘d‘]

    在原型上定义了一个引用类型的属性arr,然后通过继承创建两个对象,通过对象b访问arr属性时,由于对象b上并没有arr属性,因此,会访问b的原型对象,也就是sup对象中的arr属性,这是所有子类对象共享父类对象中的属性的实质。

    ES5中通过Object.create()方法实现原型式继承的标准API

  4. 寄生式继承
     function createPerson (obj) {
         var clone = Object.create(obj);
         clone.getName = function () {
             return this.name;
         }
         return clone;
     }
     ?
     var person = {name: ‘zhang‘, age: 18};
     var p = createPerson(person);
     console.log(person.name); // ‘zhang‘

    寄生式继承是将原型式继承以及增加实例方法这两个步骤封装成一个工厂函数,然后将生成的对象返回

    代码还是比较简单的,但是具体是干嘛用的,emmmmmm...所以,不再赘述

  5. 寄生组合式继承
     function Person (name, age) {
         this.name = name;
         this.age = age;
     }
     ?
     Person.prototype.getName = function () {
         return this.name;
     }
     ?
     Person.prototype.getAge = function () {
         return this.age;
     }
     ?
     function Student (name, age, school) {
         Person.call(name, age);
         this.school = school;
     }
     ?
     Student.prototype = Object.create(Person.prototype);
     Student.prototype.getSchool = function () {
         return this.school;
     }

    这种继承方式可以看做是组合式继承的优化,我们可以看到,其实这种方式与组合式继承其实并没有太大区别,区别仅仅在于设置Student.prototype的方式不同。组合式继承是通过new Person()的方式产生一个原型对象,而寄生组合式继承是通过Object.create()方法产生一个经过浅复制得到原型对象的一个副本。

原文地址:https://www.cnblogs.com/zhangzhengsmiling/p/10987234.html

时间: 2024-11-13 09:02:57

ES5继承模式的相关文章

es5继承和es6类和继承

es6新增关键字class,代表类,其实相当于代替了es5的构造函数 通过构造函数可以创建一个对象实例,那么通过class也可以创建一个对象实列 /* es5 创建一个person 构造函数 */ function person (name,age) { this.name = name this.age = age } /* 定义原型链上的方法sayholle */ /* 为什么要将方法定义在原型上,定义在原型上的方法,所有的实例对象都共享 不会出现没实列一个对象都重新创建一个这个方法 */

js继承模式

组合继承是js常用的继承模式,指的是将原型链和借用构造函数的技术结合在一起.其中的思想是使用原型链实现原型属性和方法的继承, 而通过借用构造函数实现对属性的继承. 例子: <script> function SuperType(name){ this.name = name; this.colors = ["red","blue"]; } SuperType.prototype.sayName = function(){ alert(this.name)

面向对象为什么要多用对象模式而少用继承模式?

进来学习java的时候遇到了一些经验说多用对象模式,少用继承模式.现在写一点感想. 面向对象的对象之间的哦和方式有继承,实现,关联,依赖,聚合和组合.其中的继承和实现是继承这类模式. 说道的一个原因就是代码污染.例如一个父类非常复杂.而一个继承了这个类的子类可能重写了一部分的方法.但是继承了全部的方法.用户在使用继承的子类的时候可能会调用没有重写的父类的方法并且如果这种方法是在子类的设计者的意图之外的操作,那么子类在继承父类的时候,可以认为不光是继承到了有用的功能,还继承到了垃圾功能,父类的代码

转 -- Python: 多继承模式下 MRO(Method Resolution Order) 的计算方式关乎super

大家可能已经知道了,在 Python 3(Python 2 的新式类)中多继承模式是使用 C3 算法来确定 MRO(Method Resolution Order) 的. 那么具体是怎么计算的呢?本文将基于 https://www.python.org/downlo... 中的几个例子来讲解 MRO 是怎么计算的. 我们首先来定义一些符号: : 用 CN 表示一个类:C1, C2, C3, ..., CN C1 C2 C3 ... CN 表示的是一个包含多个类的列表 [C1, C2, C3, .

3. 闭包_对象组合继承模式_事件轮询机制

1.谈谈闭包? (产生条件.是什么.在哪里.作用.生命周期.缺点) 产生闭包的三个条件: 函数嵌套 内部函数引用外部函数的局部变量 执行外部函数 包含被引用的局部变量的一个"对象",  通过 chrome 开发者工具可以调试查看到,就是 closure,它存在嵌套的内部函数中 作用: 延长了局部变量的存活时间, 让函数外部可以操作(读写)到函数内部的数据(变量/函数) 闭包的生命周期: 产生 :  在嵌套内部函数定义执行完时就产生了(不是在调用) 死亡 :  在嵌套的内部函数成为垃圾对

对象冒充实现继承,原型链继承方法,以及组合继承模式

function Person (){ this.name=“张三”; this.run = function(){ alert( this.name+'在运动' ) } } Person.prototype.work = function(){ alert( this.name+'在工作’ ) } // web类 继承person类 原型链+对象冒充的组合继承模式 function web(){ Person.call( this )  //  对象冒充实现继承 } var w = new w

js继承模式、命名空间、对象枚举

继承模式 继承发展史 1.传统形式--原型链 过多的继承了没用的属性 2.借用构造函数 不能继承借用构造函数的原型 每次构造函数要多走一个函数 3.共享原型 不能添加自己原型的自定义属性,会把共享原型的对象的原型的属性也更改. 4.圣杯模式 //1.原型链 Grand.prototype.lastName = "li"; function Grand(){ } var grand = new Grand(); Father.prototype = grand; function Fat

继承模式,命名空间,对象枚举

(一) 继承模式 传统形式(原型链) (1) 缺点:过多的继承了没用的属性 (2) 代码展示 //缺点:过多的继承了没用的属性 Grand.prototype.lastName = '张'; function Grand(){ this.name = '国庆'; } var grand = new Grand(); Father.prototype = grand; function Father(){ this.name = '改革'; } var father = new Father();

es5严格模式简谈

一.用法: 在全局或局部开头加上“use strict”即可 就是一行字符串,不会对不兼容严格模式的浏览器产生影响.二.不再兼容es3的一些不规则语法.使用全新的es5规范.三.两种用法: 全局严格模式 局部函数内严格模式(推荐) 四.常用的一些特点: 1.不支持with,arguments.callee,func.caller 2.变量赋值前必须声明, 3.局部this必须被赋值(Person.call(null/undefined) 赋值什么就是什么), 4.拒绝重复属性和参数 p.s.个人