精华内容
下载资源
问答
  • 2020-08-20 17:14:49

    寄生式继承是与原型式继承紧密相关的一种思路。寄生式继承的思路与寄生构造函数和工程模式类似,即创建一个仅用于封装继承过程的函数,该函数的内部以某种方式来增强对象,最后再像真的是它做了所有工作一样返回对象。下面的代码示范了寄生式继承的模式

    function object(o){
        function F(){}
        F.prototype = o;
        return new F();
    }
    
    function createAnother(original){
        var clone = object(original);//通过调用函数创建一个新对象
        clone.sayHi = function(){//以某种方式来增强这个对象
            console.log('hello')
        }
        return clone;//返回这个对象
    }

    在这个例子中createAnother函数接收了一个参数,也就是将要作为新对象基础的对象。然后,把这个对象传递给object(),将返回的结果赋值给clone,再为clone对象添加一个新的方法sayHi(),最后返回clone对象。可以像下面这样使用createAnother函数:

    var person = {
        name:"Alvin",
        friends:['Yannis',"Lucy"]
    }
    
    var anotherPerson = createAnother(person);
    anotherPerson.sayHi();//hello
    

    这个例子中的代码基于person返回了一个新对象-anotherPerson。新对象不仅具有person的所有属性和方法,而且还有自己的sayHi()方法。

    在主要考虑对象而不是自定义类型和构造函数的情况下,寄生式继承也是一种有用的模式。前面示范继承模式时使用的object()函数不是必须。任何能够返回新对象的函数都可以。

    使用寄生式继承来为对象添加函数,会由于不能做到函数复用而降低效率;这点与构造函数模式类似。

    更多相关内容
  • 下面小编就为大家带来一篇浅谈JS继承_寄生式继承 & 寄生组合式继承。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • 原型式继承 原理等同ES5的Object.create()方法, 创建一个函数,使这个函数成为括号中obj的构造函数,也就是这个函数的原型指向这个obj 然后返回这个构造函数的实例,是一个浅拷贝,新实例的引用数据类型改变会让...

    前言

    像是往原型里添加属性的那个叫原型属性
    往构造函数里添加属性的叫实例属性

    function Father(name){
      		this.name = name;
        	this.colors = ["red", "blue", "green"];
     }
     //往原型里添加属性
    Father.prototype.sayLove = function () {
        	console.log('love');
    }
     		
    console.log(Father.prototype.colors);//undefined,colors不是原型属性,是实例属性
    

    函数声明会提升,类的声明不会提升

    1、原型式继承

    1.1、创建对象的第三个方法(前两是字面量和构造函数)

    Object.create()方法
    第三种方法,很少有人能说出来。这种方式里,obj3是实例,p是obj3的原型(name是p原型里的属性),构造函数是Objecet 。接收两个参数,第一个是要以哪个obj作为原型创建,第二个参数也是个obj,往里面新添加哪些属性,浅拷贝

        var p = {name:'smyhvae'};
        var obj3 = Object.create(p,{{name:'li'}});  //此方法创建的对象,是用原型链连接的
    
    //Object.create
            obj_c = {
                name:'小李',
                sex:'male',
                love:'female',
                family:['li','ming','hon']
            }
            var a = Object.create(obj_c) 
            console.log(a.__proto__); // 下面加的属性a的原型这里就有了 wc 并没有,是f12的“欺骗”
            for(var key of a.__proto__.family){
                console.log(key)
                if(key==='Rob'){
                    console.log('OMG,Rob Is Here!!'); // 不会输出的
                }
            }
            a.family.push("Rob");
            console.log('obj_c.family: ', obj_c.family);// 'li','ming','hon','Rob'
    

    1.2、正题

    原理等同ES6的Object.create()方法。事实上,es6只是把这个继承方法规范化了而已
    创建一个函数,使这个函数成为括号中obj的构造函数(构造函数好像还是Object),也就是这个函数的原型指向这个obj
    然后返回这个构造函数的实例,是一个浅拷贝,新实例的引用数据类型改变会让原来的obj改变

            //原型链继承好像都会提升添加属性的代码。并不是这样的,可能只是f12的错误!!是个欺骗
            
    
            //原型式继承
            function Custom(obj_c)
            {
                function F(){};
                F.prototype = obj_c;
                return new F();
            }
            
            var man = Custom(obj_c);
            console.log(man.name);
            console.log('man.__proto__===obj_c',man.__proto__===obj_c);//true
    
            console.log('man.__proto__.constructor',man.__proto__.constructor);//构造函数是Object()
    

    1.3、缺点

    • 不能传递参数
    • 是浅拷贝,原型容易被篡改(原型链继承多个实例的引用类型属性指向相同,存在篡改的可能。)

    2、寄生式继承

    • 实质:寄生在原型式继承上的继承
    • 实现:在原型式继承的基础上创建了一个原实例对象之后,为新创建的原型式实例对象加入一个属性和方法,然后再返回这个实例对象,这个就是寄生在原型式继承上的寄生式继承
    • 缺点:同原型式继承
    //寄生式继承的函数
    function createAnother(original){
      var clone = Object(original); // 通过调用原生的 Object() 函数创建一个新对象,或者原型式自创的模拟object.create
      clone.sayHi = function(){  // 以某种方式来增强对象
        alert("hi");
      };
      return clone; // 返回这个对象
    }
    
    
     function Custom(obj_c)
            {
                function F(){};
                F.prototype = obj_c;
                return new F();
            }
            
            function createAnother(original) {
                var clone =Custom(original); // 通过调用 Object() 函数创建一个新对象
                clone.sayHi = function () {  // 以某种方式来增强对象
                    console.log("hi");
                };
                return clone; // 返回这个对象
            }
    
            obj_c = {
                name:'小李',
                sex:'male',
                love:'female',
                family:['li','ming','hon']
            }
    
            var anotherperson = createAnother(obj_c)
            anotherperson.sayHi() //hi
            console.log(anotherperson.love);//female
            console.log(anotherperson.__proto__);//上面的obj_c
            console.log(anotherperson.name);//小李
    

    3、寄生组合式继承

    • 理解:组合体现在子类调用了父类的构造函数,寄生体现在增强对象,原型体现在将子类的原型指向新对象
    • 步骤:先创建父类原型的副本(丢失了构造函数),再增强副本对象,使其有作为原型的资格(有了构造函数并指向子类)(喊子类来做后爸的儿子),将子类的原型指向这个副本(子类也认同了这个后爸)
    • 与组合继承相比较的优点:寄生组合只调用了一次父类的构造函数,避免了子类原型上不必要也用不到的属性,这个例子的效率更高,而且,原型链保持不变,因此, instanceof 和 isprototypeof 有效
    		function Father(name){
                this.name = name;
                this.colors = ["red", "blue", "green"];
            }
            function Child(name,sex){
                Father.call(this,name); //组合构造函数继承
                this.sayhi = function(){
                    console.log('hi');
                }
            }
            //寄生继承核心
            function inherit(subType,superType){
                let origin = Object.create(superType.prototype);//创建父类原型的副本
                origin.constructor = subType;//增强函数,使其具有作为原型的资格(前面丢失了构造函数,原型的资格必须有构造函数)
                subType.prototype = origin;//子类的原型重新指向副本
            }
            inherit(Child,Father)
    
            var instance1 = new Child("xyc", 'male');
            var instance2 = new Child("lxy", 'female');
    
            instance1.colors.push("2"); // ["red", "blue", "green", "2"]
            instance2.colors.push("3"); // ["red", "blue", "green", "3"]
    
            console.log(instance1.colors);
            console.log(instance2.colors);
    

    4、ES6类继承extends

    extends关键字主要用于类声明或者类表达式中,以创建一个类,该类是另一个类的子类。其中constructor表示构造函数,一个类中只能有一个构造函数,有多个会报出SyntaxError错误,如果没有显式指定构造方法,则会添加默认的 constructor方法

    extend 的实现和上述的寄生组合式继承方式一样

    参考文章:JavaScript常用八种继承方案

    展开全文
  • 主要介绍了JavaScript继承基础讲解,原型链、借用构造函数、混合模式、原型式继承、寄生式继承、寄生组合式继承,需要的朋友可以参考下
  • 下面小编就为大家带来一篇[js高手之路]原型式继承与寄生式继承详解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • 一、原型式继承函数 回顾一下JavaScript想...寄生式继承的思路是结合原型类继承和工厂模式的一种方式; 即创建一个封装继承过程的函数, 该函数在内部以某种方式来增强对象,最后再将这个对象返回; 三、寄生组合式

    一、原型式继承函数

    回顾一下JavaScript想实现继承的目的:重复利用另外一个对象的属性和方法.
    最终的目的:student对象的原型指向了person对象;

    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述

    二、寄生式继承函数

    寄生式(Parasitic)继承是与原型式继承紧密相关的一种思想, 并且同样由道格拉斯·克罗克福德(Douglas
    Crockford)提出和推广的;

    • 寄生式继承的思路是结合原型类继承工厂模式的一种方式;
    • 即创建一个封装继承过程的函数, 该函数在内部以某种方式来增强对象,最后再将这个对象返回;
      在这里插入图片描述

    三、寄生组合式继承

    现在我们来回顾一下之前提出的比较理想的组合继承
    组合继承是比较理想的继承方式, 但是存在两个问题:

    1. 问题一: 构造函数会被调用两次: 一次在创建子类型原型对象的时候, 一次在创建子类型实例的时候.
    2. 问题二: 父类型中的属性会有两份: 一份在原型对象中, 一份在子类型实例中.

    事实上, 我们现在可以利用寄生式继承将这两个问题给解决掉.

    • 你需要先明确一点: 当我们在子类型的构造函数中调用父类型.call(this, 参数)这个函数的时候, 就会将父类型中的属性和方法复制一份到了子类型中. 所以父类型本身里面的内容, 我们不再需要.
    • 这个时候, 我们还需要获取到一份父类型的原型对象中的属性和方法.

    **能不能直接让子类型的原型对象 = 父类型的原型对象呢? **

    • 不要这么做, 因为这么做意味着以后修改了子类型原型对象的某个引用类型的时候, 父类型原生对象的引用类型也会被修改.我们使用前面的寄生式思想就可以了

    在这里插入图片描述

    在这里插入图片描述

    实现子类(Student)继承父类(Person)的函数的核心代码:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述

    function createObject(o) {
        function Fn() {}
        Fn.prototype = o
        return new Fn()
    }
    
    function inheritPrototype(SubType, SuperType) {
        // SubType.prototype = Object.create(SuperType.prototype)
        SubType.prototype = createObject(SuperType.prototype)
        Object.defineProperty(SubType.prototype, 'constructor', {
            enumerable: false,
            configurable: true,
            writable: true,
            value: SubType
        })
    }
    
    
    function Person(name, age, friends) {
        this.name = name
        this.age = age
        this.friends = friends
    }
    Person.prototype.running = function () {
        console.log('running~')
    }
    Person.prototype.eating = function () {
        console.log('eating~')
    }
    
    function Student(name, age, friends, sno, score) {
        // 目的:实现Student继承Person的属性(本质上是在调用Person的方法,复用代码)
        Person.call(this, name, age, friends)
        this.sno = sno
        this.score = score
    }
    // 目的:让Student.prototype指向一个对象,
    // 而这个对象的原型__proto__指向Person.prototype
    // 从而实现Student继承Person中的方法
    /*Student.prototype = Object.create(Person.prototype)
    Object.defineProperty(Student.prototype, 'constructor', {
        enumerable: false,
        configurable: true,
        writable: true,
        value: Student
    })*/
    inheritPrototype(Student, Person)
    Student.prototype.studying = function () {
        console.log('studying~')
    }
    
    var stu = new Student('why', 18, ['lala'], 111, 99)
    console.log(stu)
    stu.running()
    stu.studying()
    
    
    展开全文
  • 文章目录前言一、什么是寄生式继承?二、使用实例三、总结 前言 写本《JavaScript简餐》系列文章的目的是记录在阅读学习《JavaScript高级程序设计(第4版)》一书时出现的各个知识点。虽是对读书的笔记和总结,但是...


    前言

    写本《JavaScript简餐》系列文章的目的是记录在阅读学习《JavaScript高级程序设计(第4版)》一书时出现的各个知识点。虽是对读书的笔记和总结,但是希望它轻量、简洁、犀利,不会引起阅读疲劳,可以在碎片化时间和闲暇之余轻巧地沐浴一下知识点。每篇文章只针对一个小部分进行讲解式的梳理,来达到个人复习总结和分享知识的目的。


    一、什么是寄生式继承?

    寄生式继承是与原型式继承比较接近的一种继承方式。其背后的思路类似于寄生构造函数和工厂模式:创建一个实现继承的函数,以某种方式增强对象,然后返回这个对象。老样子,先上代码:

    二、使用实例

    以下代码摘自《JavaScript高级程序设计(第4版)》

    function createAnother(original) {
        let clone = Object(original);  // 通过调用函数创建一个对象
        clone.sayHi = function() {  // 增强这个对象
            console.log('hi');
        };
        return clone;  // 返回这个对象
    }
    
    在这段代码中,createAnother()函数接收一个参数,就是新对象的基准对象。这个对象original会被传给Object()函数,然会将返回的新对象赋值给clone。接着给clone对象添加一个新方法sayHi()。最后返回这个对象。

    可以像下面这样使用以上寄生式继承:

    let person = {
        name: 'Lucy',
        friends: ['Bob', 'Jack', 'Tim']
    };
    
    let anotherPerson = createAnother(person);
    console.log(anotherPerson.name); // Lucy
    console.log(anotherPerson.friends); // [ 'Bob', 'Jack', 'Tim' ]
    anotherPerson.sayHi(); // hi
    
    这个例子基于person对象返回了一个新对象。新返回的anotherPerson对象具有person的所有属性和方法,还有一个新方法sayHi()。可见,寄生式继承同样适合主要关注对象,而不在乎类型和构造函数的场景。Object()函数不是寄生式继承所必须的,任何可以返回新对象的函数都可以在这里使用。

    三、总结

    以上就是今天要讲的内容,简单地介绍了一下寄生式继承的概念以及它的用法。下一篇我们来介绍一下寄生组合继承(传送门)。撒花~
    展开全文
  • 寄生式继承

    2021-06-17 10:04:24
    寄生式继承是与原型式继承紧密相关的一种思路。寄生式基础的思路与寄生式构造函数和工厂模拟类似: function object(O) { function F() {} F.prototype = O; return new F(); // clone = new object(); } ...
  • 寄生式继承6. 寄生式组合继承参考 继承是面向对象编程中讨论最多的话题。实现继承是ECMAScript唯一支持的继承方式,而这主要是通过原型链实现的。 1. 原型链 复习一下 构造函数、原型对象、实例对象之间的关系 ...
  • 一、原型式继承本质其实就是个浅拷贝,以一个对象为模板复制出新的对象 1 function object( o ){ 2 var G = function(){}...
  • 寄生式继承 function obj(o){ function F(){} F.prototype=o; return new F(); } function createPerson(orig){ ...
  • 一、原型式继承本质其实就是个浅拷贝,以一个对象为模板复制出新的对象 1 2 3 4 5 6 7 8 9 10 11 12 13 14 function object( o ){ var G ...
  • 什么是寄生式继承 寄生式继承的思路与寄生构造函数和工厂模式类似,即创建一个仅用于封装继承过程的函数,该函数在内部以某种方式来增强对象,后再像真的是它做了所有工作一样返回对象。 例如: function ...
  • js代码-JS的继承 1、原型继承 2、构造函数的继承 3、组合继承 4、原型式继承 5、寄生式继承 6、寄生式组合继承
  • 一、寄生式继承寄生式继承的思路与寄生构造函数和工厂模式类似,即创建一个仅用于封装继承过程的函数,该函数在内部以某种方式来增强对象,后再像真的是它做了所有工作一样返回对象。 二、createAnother()函数...
  • js代码-寄生式继承demo

    2021-07-16 16:20:03
    js代码-寄生式继承demo
  • 原型式继承 1.这种方法并没有使用严格意义上的构造函数,借助原型可以基于已有的对象创建新的对象 function object(o) { function F() {} F.prototype = o; return new F(); } // 在object()函数内部,先创建一个...
  • 原型式继承和寄生式继承
  • 一、原型链继承 特点:将父类的实例作为子类的原型 function Parent() { this.isShow = true this.info = { name: "yhd", age: 18, }; } Parent.prototype.getInfo = function() { console.log(this.info); ...
  • 继承方式五:寄生式继承

    千次阅读 2020-04-22 17:42:11
    寄生式继承的思路与寄生构造函数和工厂模式类似,即创建一个仅用于封装继承过程的函数,该函数在内部以某种方式来增强对象,最后再像真地是它做了所有工作一样返回对象。以下代码示范了寄生式继承模式 function ...
  • 组合继承(通过改变this指向进行继承) 组合继承也被称为伪经典继承,它综合了我们昨天说的原型链和盗用构造函数,将两者的优点结合在了一起。它的基本思想是使用原型链继承原型上的属性和方法,通过盗用构造函数...
  • 继承是面向对象的,使用这种方式我们可以更好地复用以前的开发代码,缩短开发的周期、提升开发效率。 那么,请你先思考几个问题: JS 的继承到底有多少种实现方式呢? ES6 的 extends 关键字是用哪种继承方式实现的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 6,737
精华内容 2,694
关键字:

寄生式继承