美文网首页饥人谷技术博客
原型、原型链、继承

原型、原型链、继承

作者: 8d2855a6c5d0 | 来源:发表于2017-07-17 23:55 被阅读0次

原型

说起原型prototype首先要说对象,JS中的对象分为两大类一类是函数对象都是Function的实例(包括Object、Array等),另一类是普通对象都是Object的实例。

  • 只有函数对象才有prototype属性,prototype也是一个普通对象(Function.prototype除外)
  • 函数对象和普通对象都有_proto_属性

原型链

function Person(name){
    this.name = name;
}
Person.prototype.sayName = function(){
    console.log('My name is :' + this.name);
}
var p = new Person("小天");
p.toString();
p.sayName();

首先看一段代码,实例p上并没有定义toString和sayName这两个方法,但是众所周知这两个方法都是存在的,p是如何拥有这这两个方法的呢,下面我们就通过这段代码来了解下原型链。

上面这张图是这段代码的原型链图,从左下角的Person实例p看起 ,p是由new Person()得来的,new操作符在这个过程中做了四件事情:
(1)创建了一个普通对象
(2)将构造函数的this替换为新创建的对象并执行构造函数(这个过程新对象就具有了构造函数的属性)
(3)将新对象的_proto属性指向构造函数的prototype(本例中就是将p._proto指向了Person.prototype,这个过程实际的意义就是使实例拥有了构造函数的方法)
(4)将新对象返回出去
当实例p调用sayName方法时,会首先找到自身的属性方法,当自身没有这个属性方法时会通过自己的_proto属性向上查找,这是就查找了Person.prototype上,因为Person.prototype拥有这个sayName方法,所以p就调用了这个方法,toString方法也是一个道理,本例中Person.prototype上也并不存在toString这个方法,那就通过Person.prototype._proto继续向上查找,由于Person.prototype也是一个普通对象,所以 Person.prototype._proto指向了Object.prototype,Object.prototype上有toString这个方法,所以p就可以调用了这个toString方法。假如这个要调用的这个方法Object.prototype上也没有就会通过Object.prototype._proto向上找就是null了,浏览器就会报错了。

解决了实例p是如何调用sayName和toString方法这两个问题,我们继续将这个原型链闭合完整。 Object、Person这两个都是函数对象,它们都是Funciton的实例,所以他们的_proto属性指向了Function.prototype,而Function比较有意思Function._proto属性指向Funciton.prototype,换句话说就是Function自己创建了自己。大概设计语言的时候就需要这样一个终点吧,要不然这样一直想上找也没有尽头啊,而Funciton.prototype_proto指向了Object.prototype。Function并不是Object的实例反而Object是Function的实例,但Funciton.prototype_proto却指向了Object.prototype。这有点不符合上面的逻辑,但这样完成了原型链的闭合,可能布兰登觉得这样能更好的提现JS“万物皆对象”的逻辑吧。

chrome控制台打印结果

继承

原型继承方法1

function Person(name, sex) {
        this.name = name;
        this.sex = sex;
    }

    Person.prototype.getName = function() {
        console.log(this.name);
    };

    function Male(name, sex, age) {
        Person.call(this, name, sex);
        this.age = age;
    }

    var F = function() {};
    F.prototype = Person.prototype;
    Male.prototype = new F();

    Male.prototype.getAge = function() {
        console.log(this.age);
    };

    var ruoyu = new Male('小明', '男', 27);
    ruoyu.getName();
    ruoyu.getAge();
    console.log(ruoyu.constructor);

原型继承方法2:Object.create
es5方法Object.create() 方法使用指定的原型对象和其属性创建了一个新的对象。
这里顺便介绍下es6的Object.setPrototypeOf方法做下区分。
Object.setPrototypeOf(obj,prototype) 方法设置一个指定的对象的原型 ( 即, 内部[[Prototype]]属性)到另一个对象或 null.

  • obj
    要设置其原型的对象。.
  • prototype
    该对象的新原型(一个对象 或 null).
function Person(name, sex) {
        this.name = name;
        this.sex = sex;
    }

    Person.prototype.getName = function() {
        console.log(this.name);
    };

    function Male(name, sex, age) {
        Person.call(this, name, sex);
        this.age = age;
    }

    Male.prototype = Object.create(Person.prototype);
    //不要忘记修改constructor指向
    Male.prototype.constructor = Male;

    Male.prototype.getAge = function() {
        console.log(this.age);
    };

    var ruoyu = new Male('小明', '男', 27);
    ruoyu.getName();
    ruoyu.getAge();
    console.log(ruoyu.constructor);

原型继承3:ES6

class Person {
        constructor(name, age) {
            this.name = name;
            this.age = age;
        }
        say() {
            console.log(this.name + ':我是社会主义接班人');
        }
    }

    class Coder extends Person {
        constructor(name, age, sex) {
            super(name, age);
            this.sex = sex;
        }
        printSex() {
            console.log(this.sex);
        }
    }

    var ruoyu = new Coder('若愚', '27', '男');

    ruoyu.say();
    ruoyu.printSex();

相关文章

  • JavaScript 原型、原型链与原型继承

    原型,原型链与原型继承 用自己的方式理解原型,原型链和原型继承 javascript——原型与原型链 JavaSc...

  • 继承

    原型链直接继承 原型链直接继承prototype 原型链继承_prototype属性 继承_构造函数绑定

  • js中的实现继承的几种方式

    大纲:原型链借用构造函数组合继承原型式继承寄生式继承寄生组合式继承 1、原型链: 什么是原型链? 原型链的基本思想...

  • Javascript 面向对象的程序设计(原型链与继承)

    继承 原型链 讲原型的时候提到过继承,设计原型的初衷就是为了继承,原型链是实现继承的主要方法。那什么是原型链,还记...

  • js基础之实现继承的几种方式

    js 实现继承的方式有: 原型链继承; 构造函数继承; 组合继承(原型链继承 + 构造函数继承)(最常用);(原型...

  • es5的部分继承以及es6的class

    一、JavaScript常用的原型继承方式 原型链继承 2,构造函数继承(对象冒充继承) 3,组合继承(原型链继承...

  • 构造函数原型的继承方式分析

    1.通过原型链继承 综上我们可以总结出 通过原型链来实现继承的原理通过原型链来实现继承的原理原型链继承方案中,父类...

  • js_继承及原型链等(四)

    js_继承及原型链等(三) 1. 继承 依赖于原型链来完成的继承 发生在对象与对象之间 原型链,如下: ==原型链...

  • JavaScript继承方式详解

    JavaScript实现继承的方式主要有两种: 原型链继承和借助构造函数继承 一、原型链继承 原型链继承的主要思想...

  • js常见的继承方式

    1.原型链继承 基于原型链查找的特点,我们将父类的实例作为子类的原型,这种继承方式便是原型链继承。 Child.p...

网友评论

    本文标题:原型、原型链、继承

    本文链接:https://www.haomeiwen.com/subject/ucaqkxtx.html