精华内容
下载资源
问答
  • 原型继承的几种方式

    2017-10-15 23:19:00
    原型继承 父级: function Parent(name){ this.name=name; } Parent.prototype.sayHello=function(){ console.log("Hello,"+this.name); } 原型链继承 function Kid(){}; Kid.prototype=new ...

    原型继承

    父级:

        function Parent(name){
            this.name=name;
        }
        Parent.prototype.sayHello=function(){
            console.log("Hello,"+this.name);
        }
    1. 原型链继承

       function Kid(){};
       Kid.prototype=new Parent("who");
      
       var k=new Kid();
       console.log(k.name); //who
       console.log(k.sayHello()); //Hello,who

      弊端:创建实例时无法向父级传参

    2. 构造继承

       function Kid(name){
           Parent.call(this,name);
       };
      
       var k=new Kid("who");
       console.log(k.name); //who
       console.log(k.sayHello()); //error

      弊端:无法获取父级原型链属性

    3. 实例继承

       function Kid(name){
           var p=new Parent(name);
           return p;
       };
      
       var k=new Kid("who");
       console.log(k.name); //who
       console.log(k.sayHello()); //Hello,who

      弊端:实例是父级的实例

    4. 拷贝继承

       function Kid(name){
           var p=new Parent(name);
           for(var item in p){
               Kid.prototype[item]=p[item];
           }
       }
      
       var k=new Kid("who");
       console.log(k.name); //who
       console.log(k.sayHello()); //Hello,who

      弊端:太占用内存

    5. 组合继承

       function Kid(name){
           Parent.call(this,name);
       }
       Kid.prototype=new Parent();
      
       var k=new Kid("who");
       console.log(k.name); //who
       console.log(k.sayHello()); //Hello,who

      弊端:调用了两次父类构造函数

    6. 寄生组合继承

       function Kid(name){
           Parent.call(this,name);
       }
       (function(){
           var p=function(){};
           p.prototype=Parent.prototype;
           Kid.prototype=new p();
       })()

      弊端:写法比较繁琐

    转载于:https://www.cnblogs.com/xiaohanblog/p/7674877.html

    展开全文
  • js原型继承的几种方式 借鉴https://www.cnblogs.com/luoguixin/p/6195902.html 1 原型链继承 2 构造函数继承(对象冒充继承) 3 组合继承(原型链继承+构造函数继承) 4 原型式继承 5 寄生组合式继承 一。原型链继承...

    js原型继承的几种方式

    借鉴https://www.cnblogs.com/luoguixin/p/6195902.html

    1 原型链继承

    2 构造函数继承(对象冒充继承)

    3 组合继承(原型链继承+构造函数继承)

    4 原型式继承

    5 寄生组合式继承

    一。原型链继承

    // An highlighted block
    unction Show(){
    this.name="run";
    }
    
    function Run(){
    this.age="20"; //Run继承了Show,通过原型,形成链条
    }
    Run.prototype=new Show();
    var show=new Run();
    alert(show.name)//结果:run
    

    二。构造函数继承(对象冒充继承)

    为了解决引用共享和超类型无法传参的问题,我们采用一种叫借用构造函数的技术,或
    者成为对象冒充(伪造对象、经典继承)的技术来解决这两种问题

    // An highlighted block
    function Box(age){
    this.name=['Lee','Jack','Hello']
    this.age=age;
    }
    function Desk(age){
    Box.call(this,age); //对象冒充,给超类型传参
    }
    var desk = new Desk(200);
    alert(desk.age);//200
    alert(desk.name);//['Lee','Jack','Hello']
    desk.name.push('AAA'); //添加的新数据,只给 desk
    alert(desk.name)//['Lee','Jack','Hello','AAA']
    

    三。组合继承(原型链继承+构造函数继承)

    借用构造函数虽然解决了刚才两种问题, 但没有原型, 复用则无从谈起。 所以, 我们需
    要原型链+借用构造函数的模式,这种模式成为组合继承。

    // An highlighted block
    function Box(age) {
    this.name = ['Lee', 'Jack', 'Hello']
    this.age = age;
    }
    Box.prototype.run = function () {
    return this.name + this.age;
    };
    function Desk(age) {
    Box.call(this, age); //对象冒充
    }
    Desk.prototype = new Box(); //原型链继承
    var desk = new Desk(100);
    alert(desk.run());
    

    四。原型式继承

    这种继承借助原型并基于已有的对象创建新对象,
    同时还不必因此创建自定义类型

    // An highlighted block
    function obj(o) { //传递一个字面量函数
    function F() {} //创建一个构造函数
    F.prototype = o; //把字面量函数赋值给构造函数的原型
    return new F(); //最终返回出实例化的构造函数
    }
    var box = { //字面量对象
    name : 'Lee',
    arr : ['哥哥','妹妹','姐姐']
    };
    var box1 = obj(box); //传递
    alert(box1.name);
    box1.name = 'Jack';
    alert(box1.name);
    alert(box1.arr);
    box1.arr.push('父母');
    alert(box1.arr);
    var box2 = obj(box); //传递
    alert(box2.name);
    alert(box2.arr); //引用类型共享了
    

    五。寄生组合式继承

    // An highlighted block
    function object(o) {
        function F() {}
        F.prototype = o;
        return new F();
    }
    
    function inheritPrototype(subType, superType) {
        var prototype = object(superType.prototype);  //创建对象
        prototype.constructor = subType;              //增强对象
        subType.prototype = prototype;                //指定对象
    }
    
    展开全文
  • 在之前的总结中,我们详细分析了原型《JS 总结之原型》,原型很大作用用于模拟继承,这一次,我们来聊原型继承的几种方式

    在之前的总结中,我们详细分析了原型《JS 总结之原型》,原型很大作用用于模拟继承,这一次,我们来聊原型继承的几种方式。

    ? 前提

    以一个父类为前提条件,列举 js 继承的继承方式:

    function Person (age) {
      this.age = age || 18
    }
    Person.prototype.sleep = function () {
      console.log('sleeping')
    }
    复制代码

    ? 方式 1:原型链继承(不推荐)

    function Programmer() {}
    
    Programmer.prototype = new Person ()
    Programmer.prototype.code = function () {
      console.log('coding')
    }
    
    let jon = new Programmer()
    jon.code() // coding
    jon.sleep() // sleeping
    
    jon instanceof Person // true
    jon instanceof Programmer // true
    
    Object.getPrototypeOf(jon) // Person {age: 18, code: ƒ}
    jon.__proto__ // Person {age: 18, code: ƒ}
    复制代码

    缺点:

    1. 无法向父类构造函数传参
    2. 父类的所有属性被共享,只要一个实例修改了属性,其他所有的子类实例都会被影响

    ? 方式 2:借用构造函数(经典继承)(不推荐)

    复制父类构造函数内的属性

    function Programmer(name) {
      Person.call(this)
      this.name = name
    }
    let jon = new Programmer('jon')
    jon.name // jon
    jon.age // 18
    
    jon.sleep() // Uncaught TypeError: jon.sleep is not a function
    jon instanceof Person // false
    jon instanceof Programmer // true
    复制代码

    优点:

    1. 可以为父类传参
    2. 避免了共享属性

    缺点:

    1. 只是子类的实例,不是父类的实例
    2. 方法都在构造函数中定义,每次创建实例都会创建一遍方法

    ? 方式 3:组合继承(推荐)

    组合 原型链继承借用构造函数继承

    function Programmer(age, name) {
      Person.call(this, age)
      this.name = name
    }
    
    Programmer.prototype = new Person()
    Programmer.prototype.constructor = Programmer // 修复构造函数指向
    
    let jon = new Programmer(18, 'jon')
    jon.age // 18
    jon.name // jon
    
    let flash = new Programmer(22, 'flash')
    flash.age // 22
    flash.name // flash
    
    jon.age // 18
    
    jon instanceof Person // true
    jon instanceof Programmer // true
    flash instanceof Person // true
    flash instanceof Programmer // true
    复制代码

    优点:融合原型链继承和构造函数的优点,是 JavaScript 中最常用的继承模式

    缺点:调用了两次父类构造函数

    ? 方式 4:原型式继承(不推荐)

    function create(o) {
      function F() {}
      F.prototype = o
      return new F()
    }
    
    let obj = {
      gift: ['a', 'b']
    }
    
    let jon = create(obj)
    let xiaoming = create(obj)
    
    jon.gift.push('c')
    xiaoming.gift // ['a', 'b', 'c']
    复制代码

    缺点:共享了属性和方法

    ? 方式 5:寄生式继承(不推荐)

    创建一个仅用于封装继承过程的函数,该函数在内部以某种形式来做增强对象,最后返回对象

    function createObj (o) {
      var clone = Object.create(o)
      clone.sayName = function () {
        console.log('hi')
      }
      return clone
    }
    复制代码

    缺点:跟借用构造函数模式一样,每次创建对象都会创建一遍方法

    ? 方式 6:寄生组合继承(最佳)

    子类构造函数复制父类的自身属性和方法,子类原型只接受父类的原型属性和方法:

    function create(prototype) {
      function Super() {}
      Super.prototype = prototype
      return new Super()
    }
    
    function Programmer(age, name) {
      Person.call(this, age)
      this.name = name
    }
    
    Programmer.prototype = create(Person.prototype)
    Programmer.prototype.constructor = Programmer // 修复构造函数指向
    
    let jon = new Programmer(18, 'jon')
    jon.name // jon
    复制代码

    进阶封装:

    
    function create(prototype) {
      function Super() {}
      Super.prototype = prototype
      return new Super()
    }
    
    function prototype(child, parent) {
      let prototype = create(parent.prototype)
      prototype.constructor = child // 修复构造函数指向
      child.prototype = prototype
    }
    
    function Person (age) {
      this.age = age || 18
    }
    Person.prototype.sleep = function () {
      console.log('sleeping')
    }
    
    function Programmer(age, name) {
      Person.call(this, age)
      this.name = name
    }
    
    prototype(Programmer, Person)
    
    let jon = new Programmer(18, 'jon')
    jon.name // jon
    复制代码

    引用《JavaScript 高级程序设计》中对寄生组合式继承的夸赞就是:

    这种方式的高效率体现它只调用了一次 Parent 构造函数,并且因此避免了在 Parent.prototype 上面创建不必要的、多余的属性。与此同时,原型链还能保持不变;因此,还能够正常使用 instanceof 和 isPrototypeOf。开发人员普遍认为寄生组合式继承是引用类型最理想的继承范式。

    ? 方式 7:ES6 extends(最佳)

    // 父类
    class Person {
      constructor(age) {
        this.age = age
      }
      sleep () {
        console.log('sleeping')
      }
    }
    
    // 子类
    class Programmer extends Person {
      constructor(age, name) {
        super(age)
        this.name = name
      }
      code () {
        console.log('coding')
      }
    }
    
    let jon = new Programmer(18, 'jon')
    jon.name // jon
    jon.age // 18
    
    let flash = new Programmer(22, 'flash')
    flash.age // 22
    flash.name // flash
    
    jon instanceof Person // true
    jon instanceof Programmer // true
    flash instanceof Person // true
    flash instanceof Programmer // true
    复制代码

    优点:不用手动设置原型。

    缺点:新语法,只要部分浏览器支持,需要转为 ES5 代码。

    ? 参考

    转载于:https://juejin.im/post/5c1f9fc0f265da6125781973

    展开全文
  • js原型继承的几种方式 原型链继承 构造函数继承(对象冒充继承) 组合继承(原型链继承+构造函数继承) 原型式继承 寄生组合式继承 1.原型链继承 什么是原型链??? 这里是我找到的几个比较清楚的图片 众所周知...

    js原型继承的几种方式

    1. 原型链继承
    2. 构造函数继承(对象冒充继承)
    3. 组合继承(原型链继承+构造函数继承)
    4. 原型式继承
    5. 寄生组合式继承

    1.原型链继承

    什么是原型链???
    这里是我找到的几个比较清楚的图片
    在这里插入图片描述

    在这里插入图片描述
    众所周知,每个构造函数都有一个原型对象,原型对象都包括一个指向构造函数的指针,而实例都包括一个指向原型对象的内部指针,如果我们将原型对象等于另一个构造函数的实例,此时的原型对象将包含一个指向另一个原型的指针,层层递进就形成了原型链。

    function superf() {
        this.name = "xuxiaotong";
    }
    
    function subf() {
        this.age = "21"; 
    }
    subf.prototype = new superf();//subf继承了superf,通过原型,形成链条
    var test = new subf();
    console.log(test.name) //xuxiaotong
    

    有两个问题:引用共享和超类无法传参。

    2.构造函数继承(对象冒充继承)

    function superf(name) {
        this.name = name
    }
    superf.prototype.getname = function(){
        return this.name 
    }
    
    function subf(name,age) {
        superf.call(this,name)
        this.age = age; 
    }
    
    
    var test = new subf("xuxiaotong",21);
    console.log(test.name) //xuxiaotong
    console.log(test.age) //21
    

    借用构造函数虽然解决了刚才两种问题, 但没有原型, 复用则无从谈起。 所以, 我们需要原型链+借用构造函数的模式,这种模式成为组合继承。

    3.组合继承(原型链继承+构造函数继承)

    //原型链加构造函数继承
    function spuerf(name){
        this.name = name
    }
    spuerf.prototype.getname = function(){
        return this.name
    }
    
    function subf(name,age,hobby){
        spuerf.call(this,name)
        this.age = age
        this.hobby =hobby
    }
    
    subf.prototype = new spuerf()
    
    subf.prototype.getintro = function(){
        return "我叫:" + this.name +"\n" +this.age + "岁" +"\n"+ "爱好是:" +this.hobby
    }
    var test =  new subf("xutong",21,"敲代码")
    console.log(test.getintro())
    
    

    在这里插入图片描述
    虽然可以解决上面的个问题,但是这种方法在执行的过程中会两次调用超类构造函数(耗内存)。

    4.原型式继承

    function obj(o) { 
        function F() { } 
        F.prototype = o; 
        return new F(); 
    }
    var test  = {
        name:"xuxiaotong",
        age:21,
        getintro:function(){
            return this.name + "已经" + this.age + "了"
        }
    
    }
     var test1 = obj(test)
    
     console.log(test1.name)  //xuxiaotong
     console.log(test1.age)  //21
     test.age = 22
     console.log(test.age)  //22
     console.log(test1.getintro())  //xuxiaotong已经22了
    

    上例子中,在obj()函数内部,先创建一个临时性的构造函数,然后将传入的对象作为这个构造函数的原型,最后返回一个临时类型的实例。

    该继承需要有一个对象可以作为另一个对象的基础,在根据具体需求加以修改。

    5.寄生式继承

    var createAnother = function(sub){
        var clone = Object(sub)
        clone.getintro = function(){
            return this.name + this.age
        }
        return clone
    }
    
    var test  = {
        name:"xuxiaotong",
        age:21,
        
    
    }
     var test1 = createAnother(test)
    
     console.log(test1.getintro())  //xuxiaotong已经22了
    
    
    

    方法在函数中定义,无法得到复用。

    6.寄生组合式继承

    寄生组合式继承解决了组合式继承两次调用的问题。

    组合式继承两次调用:
    在这里插入图片描述
    下面是寄生组合式继承

    function inheritPrototype(subType, superType){
        var prototype = object(superType.prototype); //创建对象
        prototype.constructor = subType; //增强对象
        subType.prototype = prototype; //指定对象
    }
    function SuperType(name){
        this.name = name;
        this.colors = ["red", "blue", "green"];
    }
    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);
    
    };
    
    展开全文
  • 平时不怎么用的一些知识,过段时间就开始模糊不清了,这已经不知道是第次再回头来看原型继承的方式了,索性重新整理一遍,方便下次回顾,若有不正确或需要补充的欢迎留言 在ES6之前,JS实现继承的方式不止一,...
  • 原型继承 父级: function Parent(name){ this.name=name; } Parent.prototype.sayHello=function(){ console.log("Hello,"+this.name); }  原型链继承function Kid(){}; Kid.prototype=new Pa
  • 这个示例中的inheritPrototype()函数实现了寄生组合式继承的最简单形式。这个函数接收两个参数:子类型构造函数和超类型构造函数。在函数内部,第一步是创建超类型原型的一个副本。第二步是为创建的副本添加...
  • 原型:继承的几种方式

    2019-03-04 01:51:58
    继承的几种方式 1.原型继承: 继承私有属性和公有属性,父类的所有属性,都变成了子类的公有属性 2.中间类继承: 3.call继承 继承私有 4.寄生组合式继承 用call继承和Object.create()配合 ...
  • 原型链以及继承的几种方式

    千次阅读 2019-03-05 19:13:54
    原型链以及继承的几种方式学习原型链前需要了解原型继承的几种方式 学习原型链前需要了解 使用构造函数模式创建的对象实例,都有一个constructor(构造函数) 属性,该属性指向构造函数。 function Person (name, ...
  • 继承的实现方法: 原型链是实现继承的主要方式.改变作用域也算一,也就是call()或者apply().  3.构造函数式继承: (继承的是属性)将父类的构造函数在子类的函数体中执行,并且通过call改变this指向...
  • 原型继承 原型继承方式有很多多种,今天主要说四常用方法 一 子类原型继承父类实例(原型链继承)
  • 学习原型链前需要了解使用构造函数模式创建对象实例,都有一个constructor(构造函数)属性,该属性指向构造函数。function Person (name, age, job) {this.name = name;this.age = age;this.job = job;this.sayName...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 638
精华内容 255
关键字:

原型继承的几种方式