原型与原型链

作者: _ClariS_ | 来源:发表于2019-07-27 18:26 被阅读11次

    公用属性

    我们知道,所有对象都有 toString 和 valueOf 属性,但如果给每一个对象都分配一个 toString 和 valueOf ,会十分地占内存,如图

    每一个对象都分配 toString 和 valueOf

    显然这么做很蠢。

    因此,JS 的做法是把 toString 和 valueOf 放在一个对象里(暂且叫做公用属性组成的对象),然后让每一个对象的 _ _ proto _ _ 存储这个「公用属性组成的对象」的地址。

    举个栗子
    执行 o1.toString() 时,首先进入对象 o1 查找是否存在 .toString 属性,如果没有,再通过 _ _ proto _ _ 进入所有对象的公用属性中找到 toString 函数

    同时,这时候如果再声明一个对象 o2 ,我们会发现虽然 o1 与 o2 不相等,但却有 o1.toString === o2.toString,这也说明了对象确实是存在公用属性的

    另外,除 Object 对象之外,Number、String、Boolean 对象都分别有自己独有的公用属性,以 Number 对象为例:

    每个实例对象( object )都有一个私有属性(称之为 _ _ proto _ _ )指向它的构造函数的原型对象(prototype )。该原型对象也有一个自己的原型对象( _ _ proto _ _ ) ,层层向上直到一个对象的原型对象为 null。根据定义,null 没有原型,并作为这个原型链中的最后一个环节。

    树形结构图

    上图中红色的连线就被称之为原型链

    代码

    即便不写代码,浏览器也是会有 prototype 的,且浏览器的 prototype 无法被修改

    image.png

    注意:Object.prototype对象也有_ _ proto _ _属性,但它比较特殊,为null

    重要公式

    通用公式

    var 对象 = new 函数()
    对象.__proto__ === 对象的构造函数.prototype
    

    注意:
    一、构造函数的概念:

    任何函数都可以当成构造函数 function CreateFunc(){ }
    只要把一个函数通过new的方式来进行调用,我们就把这一次函数的调用方式称之为:构造函数的调用
    new CreateFunc(); 此时CreateFunc就是一个构造函数
    CreateFunc(); 此时的CreateFunc并不是构造函数
    也可以说,构造函数就是返回一个新的对象的函数

    二、七种基本数据类型中只有 number、string、boolean、object(array、function)分别有相应的构造函数 Number()、String()、Boolean()、Object()、Array()、Function(),undefined和null是没有构造函数的。

    推论

    var number = new Number()
    number.__proto__ = Number.prototype
    注意大小写,number 和 Number 是不同的
    //
    var object = new Object()
    object.__proto__ = Object.prototype
    //
    var function = new Function()
    function.__proto__ = Function.prototype
    

    另外,所有函数都是由 Function 构造出来的,所以

    Number.__proto__ = Function.prototype // 因为 Number 是函数,是 Function 的实例
    Object.__proto__ = Function.prototype // 因为 Object 是函数,是 Function 的实例
    Function.__proto__ == Function.prototye // 因为 Function 是函数,是 Function 的实例!
    

    相关文章

      网友评论

        本文标题:原型与原型链

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