原型和原型链(包括ES6的class继承)

本文详细介绍了JavaScript中的原型和原型链概念,包括__proto__、constructor和prototype属性。通过实例展示了如何使用原型实现对象继承,并对比了ES6中class的继承方式。同时,解释了类之间的关系以及实例与原型的关联,强调了属性和方法查找的顺序。最后,讨论了子类与父类的原型关系及其特点。
摘要由CSDN通过智能技术生成

万物皆对象,万物皆为空(看下方关系图)

原型--保存所有子对象的共有属性值和方法的父对象;

原型链--由各级子对象的__proto__属性连续引用形成的结构;

三个属性:__proto__ ,constructor ,prototype

ES6以前写法

代码演示:

    function Person(name, age) {
        this.name = name
        this.age = age
        this.say = function () {
            return '姓名:' + this.name; //console.log(this.name);
        }
    }
    //当函数创建的时候就会携带上一个prototype属性,这个属性指向Person.prototype,也就是原型对象

    Person.prototype.money = 20;
    Person.prototype.run = function () {
        console.log('跑步');
    };
    /**
     * 注意!run()和money不是定义在Person上的,是原型对象Person.prototype的
     * 错误用法:console.log(Person.money); //undefined
     */


    //实例化对象
    var p1 = new Person('张三', 12);
    //1、实例化对象p1 带有__proto__属性,__?__这种形式的属性一般都是js内部属性,例[[scope]]
    //2、p1.__proto__:js的内部属性都会携带Array Function Date...
    console.log(p1.money);
    console.log(p1.__proto__ === Person.prototype); //true

    console.log(Person.prototype);
    //Person.prototype 携带 constructor
    console.log(Person.prototype.constructor === Person);

关系图

Function对象与Object对象之间的关系

Function是顶层的构造器,Object是顶层的对象

顶层现有null <-- Object.prototyepe <-- Function.prototype <-- Function  (通过__proto__属性)

从原型上来说:Function继承了Object

从构造器上来说:Function构造了Object

function Object() { }

应用:继承

        function Person(name, age) {
            this.name = name
            this.age = age
            this.say = function () {
                return '姓名:' + this.name; //console.log(this.name);
            }
        }
        var p1 = new Person('张三', 12);
        var p2 = {
            name: '李四'
        }
        /**
         * 注意!p1是Person实例化的对象,p1.__proto__指向原型对象Person.prototype
         * 通过让对象p2的__proto__属性指向p1,构成一条原型链
         * 对象p2则可以通过原型链访问p1和Person构造函数上的属性和方法
          */
        p2.__proto__ = p1;
        console.log(p2.say());//'李四',p2的name属性已重新赋值
        console.log(p1.say());//'张三',p2不影响p1

ES6支持class继承

ES6的class只是对于function()的一种新的写法,不同点是类(class)的写法,以及类之间的继承关系(exten)。ES6的类与c++,java的类还是有所不同的

class Person {
    constructor(name) {
        this.name = name
    }
    sayHi() {
        return `你好!${this.name}`
    }
}
class Student extends Person{
    constructor(name,number) {
        super(name);
        this.number = number
    }
}

         1、

const zhangsan = new Student('张三',1001);
console.log(zhangsan.name);             //张三
console.log(zhangsan.sayHi());          //你好!张三
console.log(Student.prototype.sayHi());     //你好!undefined
console.log(zhangsan.__proto__===Student.prototype);    //true

/**
 *  函数和属性应该是定义在类的显式原型(.prototype)上的,而非类本身 
 * 因为在调用一个属性或方法的时候,该对象先在自身找,
 * 若没有再到隐式原型(.__proto__)上找,指向类的显式原型(.prototype)
 * */ 

        2、

console.log(zhangsan instanceof Student);       //ture
console.log(zhangsan instanceof Person);       //ture
console.log(Student instanceof Person);       //flase  子类和父类是继承关系,子类有自己的构造器
console.log(Student instanceof Object);       //ture
console.log(Object instanceof Function);       //ture

console.log(Person.__proto__===Function.prototype);        //true
console.log(Function.__proto__===Function.prototype);    //true

顶层的构造器依旧是Function,Object和Function的关系与之前所讲一致,重申:class只是一种新的写法形式,参考上面关系图

        3、

/**

 *  子类和父类的原型关系  

 *  子类的__proto__指向父类本身,而非父类的显式原型prototype

 *  子类显式原型prototype的隐式原型__proto__指向父类的显式原型

 * */

console.log(Student.__proto__===Person);    // true

console.log(Student.__proto__===Person.prototype);    //false

console.log(Student.prototype.__proto__ === Person.prototype)  //true

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值