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

    千次阅读 2018-10-18 16:52:41
    原型继承 首先创建一个构造函数,并为其设置私有属性和公有属性。 // 定义一个人类 function Person (name) { // 属性 this.name = name; // 实例方法 this.sleep = function(){ console.log(this.name + '...

    原型继承

    首先创建一个构造函数,并为其设置私有属性和公有属性。

    // 定义一个人类
        function Person (name) {
          // 属性
          this.name = name;
          // 实例方法
          this.sleep = function(){
            console.log(this.name + '正在睡觉!');
          }
        }
        // 原型方法
        Person.prototype.eat = function(food) {
          console.log(this.name + '正在吃:' + food);
        };
    

    开始继承

    原型继承有很多种方法,接下来就记录下我已知的几种方法。

    第一种 原型链继承

    重点圈起来:将父类实例赋值给子类原型对象

    	// 创建子类、添加子类属性。
       function arrange(name){
         this.name = name;
         this.goShop = function(food){
           console.log(name + '叫你去买'+ food)
         }
       }
       // 将父类实例赋值给子类原型对象
       arrange.prototype = new Person();
       // 将constructor指向本身,保证原型链不断。
       arrange.prototype.constructor = arrange; 
    
       //创建arrange新实例,也是Person实例;
       var newObj = new arrange('李四'); 
       console.log(newObj instanceof Person)  //true
       console.log(newObj instanceof arrange) //true
       // 原型链继承成功,可以访问父类所有属性;
       console.log(newObj)
       console.log(newObj.name) // 李四
       newObj.sleep(); // 李四正在睡觉!
       newObj.eat('苹果'); // 李四正在吃:苹果
       newObj.goShop('香蕉'); // 李四叫你去买香蕉
    

    第二种 构造继承

    重点圈起来:执行父构造,将This指向本身,拉取父私有属性

    	// 创建子类、添加子类属性。
    	function arrange(name){
          Person.call(this,name) // 执行父构造,将This指向本身,拉取父私有属性;
        }
        arrange.prototype.getName = function(){
          console.log('我叫' + this.name)
        }
        var newObj = new arrange('李四');
        console.log(newObj)
        console.log(newObj.name) //李四
        newObj.sleep() // 李四正在睡觉!
        newObj.getName() //我叫李四
    

    第三种 组合继承

    重点圈起来:构造继承与原型继承组合。注意注释区域,切勿在继承时使用此方法重写或添加方法,否则将会修改整个原型,导致崩塌。

    	// 创建子类、添加子类属性。
    	function arrange(name){
          Person.call(this,name) // 执行父构造,将This指向本身,拉取父私有属性;
        }
        // 将父类实例赋值给子类原型对象
        arrange.prototype = new Person(); // 直接拉取父类实例继承原型
        // 将constructor指向本身,保证原型链不断。
        arrange.prototype.constructor = arrange;
        
        // 下面这个方法会替换整个原型对象
        // arrange.prototype = {
        //   init:function(){
        //     console.log('我会替换整个原型')
        //   }
        // }
        // 必须在原型实例继承之后,在给子类原型添加方法,或重写方法,请使用以下方法
        arrange.prototype.eat = function() {
          console.log(this.name + '重写了此方法');
        };
        arrange.prototype.addFn = function(){
          console.log(this.name + '添加了新方法' );
        }
        
        var newObj = new arrange('王五');
        console.log(newObj)
        newObj.eat(); // 王五重写了此方法
        newObj.addFn(); // 王五添加了新方法
    

    第四种 克隆原型链继承

    重点圈起来: 将等待继承的原型对象克隆,再赋值给继承的原型对象。此种方法会脱轨,不在同一原型链上

    	// 创建子类、添加子类属性。
    	function arrange(name){
          this.name = name;
          this.goShop = function(food){
            console.log(name + '叫你去买'+ food)
          }
        }
        // 创建克隆类型
        function Clone(obj){
          for(var key in obj){
            this[key] = typeof obj[key] == 'object' ? new Clone(obj[key]) : obj[key];
          }
        }
        // 使用Clone构造函数继承原型
        arrange.prototype = new Clone(Person.prototype); 
        // 将constructor指向本身,保证原型链不断。
        arrange.prototype.constructor = arrange; 
    
        //创建arrange新实例,也是Clone实例,却不在是Person实例;
        var newObj = new arrange('李四'); 
        console.log(newObj instanceof Person)  //false
        console.log(newObj instanceof arrange) //true
        console.log(newObj instanceof Clone) //true
        // 克隆成功,可以访问克隆对象的原型对象;
        console.log(newObj)
        console.log(newObj.name) // 李四
        newObj.eat('苹果'); // 李四正在吃:苹果
        newObj.goShop('香蕉'); // 李四叫你去买香蕉
    

    第五种 寄生组合继承

    重点圈起来: 将父类原型对象直接赋值给一个空属性的构造函数,再将空属性的构造函数实例赋值给子类原型对象,其根本是为了解决父实例继承的出现的两次构造。

    	// 创建子类、添加子类属性。
    	function arrange(name){
          Person.call(this,name)
          this.shop = function(){
            console.log(this.name + '去买好吃的,好吃就多吃点')
          }
        }
    
        (function(){
          // 创建一个没有实例方法的类
          var nullFn = function(){};
          nullFn.prototype = Person.prototype;
          //将实例作为子类的原型
          arrange.prototype = new nullFn();
           // 将constructor指向本身,保证原型链不断。
          arrange.prototype.constructor = arrange;
        })();
        
        var newObj = new arrange('老王');
        console.log(newObj)
        newObj.shop(); // 老王去买好吃的,好吃就多吃点
        newObj.sleep(); // 老王正在睡觉!
        newObj.eat('芭蕉'); // 老王正在吃:芭蕉
    

    学习犹如逆水行舟,有舟就上。别问为什么,吾乃不踩坑学不会系列。

    展开全文
  • 原型链以及继承几种方式

    千次阅读 2019-03-05 19:13:54
    原型链以及继承几种方式学习原型链前需要了解原型继承几种方式 学习原型链前需要了解 使用构造函数模式创建的对象实例,都有一个constructor(构造函数) 属性,该属性指向构造函数。 function Person (name, ...

    学习原型链前需要了解

    只要创建一个新函数,就会根据特定的规则为该函数创建一个 prototype 属性,这个属性是一个指针,指向一个对象。这个对象的用途是包含可以由特定类型的 所有实例 共享的属性和方法,这个对象就是通过调用构造函数创建的对象实例的原型对象。 所有的原型对象都会默认获得一个constructor(构造函数) 属性该属性指向构造函数。
    当调用构造函数创建一个实例之后,该实例内部会包含一个指针(属性),指向构造函数的原型,我们可以称这个指针为 [[Prototype]]

    function Person (name, age, job) {
        this.name = name;
        this.age = age;
        this.job = job;
        this.sayName = function () {
            alert(this.name)
        }
    }
    var person1 = new Person(“Nicholas”, 29, “Sofware Engineer”)
    var person2 = new Person(“Greg”, 27, “Doctor”)
    
    alert(person1.constructor == Person) // true
    alert(person2.constructor == Person) // true
    
    //创建出来的所有对象即使Object的实例,同时也是Person的实例
    

    原型链

    构造函数,原型和实例的关系
    每一个构造函数都有一个原型对象,原型对象包含一个指向构造函数的指针,而每个实例都包含一个指向构造函数的原型对象的内部指针

    原型链
    如果让一个原型对象等于另一个类型的实例,层层递进,构成实例与原型的链条,这就是原型链

    创建了自定义的构造函数,其原型对象默认只会取得 constructor 属性;其他方法都是从Object 继承来的
    当调用构造函数创建一个实例之后,该实例内部会包含一个指针(属性),指向构造函数的原型,我们可以称这个指针为 [[Prototype]]

    Function(Object)包含 prototype(原型对象指针)
    prototype(原型对象指针)包含constructor(构造函数)属性
    constructor(构造函数)属性包含指向原型对象所在函数的指针

    包含
    包含
    包含
    Function构造函数
    prototype
    constructorr
    指向原型对象所在的构造函数

    注意:
    如果使用如下方式给原型赋值,则constructor属性不再指向原型对象躲在的函数,指向Object构造函数

    Person.prototype = {
          name: '哈哈'
         }
    

    继承的几种方式

    js主要是通过原型链实现继承,原型链的构建是通过将一个类型的实例赋值给另外一个构造函数的原型实现的
    原型链继承
    基本代码

    function SuperType () {
        this.property = true
    }
    SuperType.prototype.getSuperValue = function () {
        return this.property
    }
    function SubType () {
        this.subproperty = false
    }
    // 继承了SuperType //
    SubType.prototype = new SuperType()
    SubType.protype.getSubValue = function () {
        return this.subproperty
    }
    var instance = new SubType()
    

    实现的本质:重写原型对象,用一个新的类型的实例去替代
    在这里插入图片描述
    SubType Prototype === SuperType构造函数的实例
    注意:
    1.默认的原型
    所有的引用类型都默认继承Object,这个继承也是通过原型链实现的在这里插入图片描述
    2.原型链的问题
    a.对象实例共享所有继承的属性和方法
    b.创建子类型的实例的时候,不能传递参数

    借用构造函数继承
    基本代码

    function SuperType () {
        this.colors = ["red", "blue", "green"]
    }
    function SubType () {
        // 继承了SuperType
        SuperType.call(this)
        // 只能继承构造函数上的属性
    }
    

    实现的本质:在子类构造函数的内部调用超类型构造函数,使用aapply()和call() 方法
    注意:
    1.函数复用性不高
    2.只能继承实例上的属性,原型上的方法不可见

    组合继承(伪经典继承)
    基本代码

    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)  // 第二次调用SuperType()
        this.age = age
    }
    //继承方法
    SubType.prototype = new SuperType()  // 第一次调用 SuperType()
    Subtype.prototype.sayAge = function () {
        alert(this.age)
    }
    

    实现思路:使用原型链实现对原型属性和方法的继承,通过借用构造函数来实现对实例属性的继承
    注意:
    组合继承避免了原型链和借用构造函数的缺陷,融合了他们的优点,成为js中最常用的继承方式。

    原型式继承
    基本代码

    function object (o) {
       function F(){}
       F.prototype = o
       return new F()
    }
    

    实现本质:object()函数对传入其中的对象执行了一次浅复制
    注意:
    可以在不必预先定义构造函数的情况下实现继承,其本质是执行对给定对象的浅复制,而复制的副本还可以得到进一步的改造
    问题还是包含引用类型的属性都会被共享

    寄生式继承
    基本代码

    function createAnother (original) {
       var clone = object(original)  // 通过调用函数创建一个新对象
       clone.sayHi = function () {   // 以某种方式来增强这个对象
           alert("hi")
       }
       return clone                  // 返回这个对象
    }
    

    实现本质和寄生构造函数还有工厂模式类似
    注意:
    基于某个对象或者某些信息创建一个对象,然后增强对象,最后返回对象,为了解决组合继承模式由于多次调用超类型构造函数而导致的低效率问题,可以将这个模式与组合继承一起使用

    寄生组合式继承
    基本代码

    	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)
    

    实现本质:借用构造函数来继承属性,通过原型链的混成形式来继承方法
    注意:
    高效率只调用了一次构造函数,集寄生式继承和组合继承的优点于一身,是实现基于类型继承的最有效方式

    小结:
    JavaScript主要通过原型链实现继承。原型链的构建是通过将一个类型的实例赋值给另一个构造函数的原型实现的。
    使用最多的继承模式是组合继承,这种模式使用原型链继承共享的属性和方法,通过借用构造函数继承实例属性

    注:博客新手,文章有误请大家指出,不胜感激
    之后随笔应该会同时在CSDN和掘金上更新,下面是我的掘金主页
    江湖不渡!的主页

    展开全文
  • 【前端Js】原型继承几种方式.pdf
  • 原型:继承几种方式

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

    继承的几种方式

    1.原型继承: 继承私有属性和公有属性,父类的所有属性,都变成了子类的公有属性

    2.中间类继承:

    3.call继承

    • 继承私有

    4.寄生组合式继承

    • 用call继承和Object.create()配合
    展开全文
  • 面试官:说说JS几种方式继承方式?我:这个...

    借助构造函数实现继承

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>类与继承</title>
    </head>
    <body>
        <script>
            function a(){
                this.a=1;
            }
            function b(){
                a.call(this);
                this.b=2;
            }
            console.log(new b);
        </script>
    </body>
    </html>
    

    结果

    存在问题

    上述方式,是通过改变 a 构造函数运行时 this 指向,指向 b,但是 a 原型链上的东西没有继承。

    例如:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>类与继承</title>
    </head>
    <body>
        <script>
            function a(){
                this.a=1;
            }
            a.prototype.ma = function(){
                console.log('aaa');
            }
            function b(){
                a.call(this);
                this.b=2;
            }
            console.log(new b);
        </script>
    </body>
    </html>
    


    因此,通过构造函数来实现的继承,只能继承父类构造函数的属性,如果原型 prototype上面还有方法甚至原型链上的方法,不会继承。

    借助原型链实现继承

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>类与继承</title>
    </head>
    <body>
        <script>
            function a(){
                this.a=1;
            }
            function b(){
                this.b=2;
            }
            b.prototype = new a();
            console.log(new b);
        </script>
    </body>
    </html>
    

    结果

    存在的问题

    首先读者请看如下代码:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>类与继承</title>
    </head>
    <body>
        <script>
            function a(){
                this.a=1;
                this.arr=[1,2,3,4,5,];
            }
            function b(){
                a.call(this);
                this.b=2;
            }
            b.prototype = new a();
            let b1 = new b();
            let b2 = new b();
            b1.arr.push(100);
            console.log(b1,b2);
        </script>
    </body>
    </html>
    


    从以上结果来看,当我们修改某一个对象时,该函数所产出的所有新实例都会发生改变,这就造成了 数据污染 问题,肯定不是我们想要的。(因为它们引用的是同一个父类实例对象)

    组合方式实现继承1

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>类与继承</title>
    </head>
    <body>
        <script>
            function a(){
                this.name='aaa';
                this.arr=[1,2,3,4,5];
            }
            function b(){
                a.call(this);
                this.type='bbb';
            }
            b.prototype = a.prototype;
            let b1 = new b();
            let b2 = new b();
            b1.arr.push(100);
            console.log(b1,b2);
            console.log(b1.constructor);
            console.log(b2.constructor);
        </script>
    </body>
    </html>
    

    结果

    存在的问题

    如上图结果图所示,拿得是父类的原型对象,依旧没有自己的 constructor。(和父类的原型对象是同一个对象,导致 constructor也指向父类)

    组合方式实现继承2

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>类与继承</title>
    </head>
    <body>
        <script>
            function par(){
                this.name='aaa';
                this.arr=[1,2,3,4,5];
            }
            function child(){
                par.call(this);
                this.type='bbb';
            }
            //这里使用Object.create()方法,和之前直接用a.prototype来说,它创建了
            //一个中间对象,和父类不是指向同一个区域了
            //这样就能区分父类和子类的原型对象了,达到父类和子类原型对象的隔离效果
            child.prototype = Object.create(par.prototype);
            //由于隔离了父类子类的原型对象,我们就可以指定子类自己的constructor
            child.prototype.constructor = child;
            let child1 = new child();
            let child2 = new child();
            child1.arr.push(100);
            console.log(child1,child2);
            //判断构造函数
            console.log(child1.constructor);
            console.log(child2.constructor);
        </script>
    </body>
    </html>
    

    结果

    展开全文
  • 在讲几种继承方式的优缺点之前,先给大家介绍一下在javascript中对各种属性的分类 在javascript中,数据分为简单数据和复杂数据,简单数据在对象里称为基本属性,而数组,函数在对象里称为引用属性(数组,函数其实...
  • 原型继承 父级: function Parent(name){ this.name=name; } Parent.prototype.sayHello=function(){ console.log("Hello,"+this.name); }  原型链继承function Kid(){}; Kid.prototype=new Pa
  • javascript 的七种继承方式(一)原型

    万次阅读 多人点赞 2020-08-19 10:57:59
    ECMAScript中描述了原型链的概念,并将原型链作为实现继承的主要方法。其基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法。简述一下构造函数、原型和实例的关系:每个构造函数都有一个原型对象,反...
  • 主要介绍了JS实现继承几种常用方式,结合实例形式分析了JavaScript继承的四种常见实现方式,包括原型继承、构造继承、组合继承及寄生组合继承,需要的朋友可以参考下
  • 继承的实现方法: 原型链是实现继承的主要方式.改变作用域也算一,也就是call()或者apply().  3.构造函数式继承: (继承的是属性)将父类的构造函数在子类的函数体中执行,并且通过call改变this指向...
  • JS中继承几种方式

    万次阅读 多人点赞 2019-05-11 23:24:25
    JS中继承几种方式
  • 今天要介绍的是,对象之间的”继承”的几种方式。首先有一个问题,为什么继承还有几种方式呢?你看不管是java还是C++,继承就是继承,哪有几种继承方式,不过Javascript 是一种灵活的语言,之所以灵活,说不好听点...
  • JS里常用的有如下两种继承方式原型继承(对象间的继承) 类式继承(构造函数间的继承) 2.知识剖析 JavaScript语言的对象体系,不是基于“类”,而是基于构造函数(constructor)和原型(prototype)。 * ...
  • 原型链实现继承几种模式

    千次阅读 2016-07-02 13:31:29
    原型链很强大,可以用来实现继承,但也存在一些问题。其中最主要的问题是来自包含引用类型值的原型。看如下例子:function Super() { this.colors = ['red', 'blue', 'green']; } function Sub() { } Sub.prototype...
  • JavaScript实现继承几种方式

    千次阅读 2018-03-24 00:06:23
    javascript实现继承几种方式 JS作为面向对象的弱类型语言,继承也是其非常强大的特性之一。 JS继承的实现方式 既然要实现继承,那么首先我们得有一个父类,代码如下: // 定义一个动物类 function ...
  • 再谈javascript原型继承

    2020-10-25 06:38:35
    Javascript原型继承是一个被说烂掉了的话题,但是自己对于这个问题一直没有彻底理解,今天花了点时间又看了一遍《Javascript模式》中关于原型实现继承的几种方法,下面来一一说明下,在最后我根据自己的理解提出了一...
  • 继承几种方式: ① 使用构造函数实现继承 function Parent(){ this.name = 'parent'; } function Child(){ Parent.call(this); //在子类函数体里面执行父类的构造函数 this.type = 'child';//子类自己的属性 } ...
  • js继承几种实现方式

    千次阅读 2020-06-23 19:39:28
    js有几种经典的继承方式。比如原型继承、构造函数继承、组合继承、寄生组合继承、ES6继承。让我们一一分析并实现。同时了解每种方案的优缺点。 文章目录1.原型继承优点缺点2.构造函数继承优点缺点3.组合继承优点...
  • JS继承几种方式

    千次阅读 2018-03-09 15:40:14
    1. 借助构造函数实现继承 function Parent() { this.name = 'parent';...缺点:只能实现部分继承。Child只能继承Parent构造函数里面的属性。不能继承Parent原型链上的。 function Pare...
  • js对象继承几种方式

    千次阅读 2018-12-04 16:50:58
    构造函数使用this关键字给所有属性和方法赋值(即采用类声明的构造函数方式)。因为构造函数只是一个函数,所以可以使parent这个函数成为children的方法,然后调用它。children就会收到parent的构造函数中定义的属性...
  • js实现继承几种方式

    千次阅读 2016-12-25 17:17:08
    http://www.jb51.net/article/44875.htm... 一,js中对象继承 js中有三种继承方式 1.js原型(prototype)实现继承 复制代码 代码如下:        function Person(name,age){   this.name=name;   this.age=age;
  • //父类 // 定义一个动物类 function Animal (name) { // 属性 this.name = name || 'Animal'; // 实例方法 this.sleep = function(){ console.log(this.name + '...// 原型方法 Animal.prototype.eat = funct...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 70,652
精华内容 28,260
关键字:

原型继承的几种方式