美文网首页
JS的原型和原型链

JS的原型和原型链

作者: 饥人谷_小霾 | 来源:发表于2019-12-06 20:50 被阅读0次

    原型/共用属性

    所有对象都有 toString 和 valueOf 属性,那么我们是否有必要给每个对象一个 toString 和 valueOf 呢?答案是不需要的。因为JS每次声明一个对象都要写一次这些方法这样写的话会非常占用内存,而且内存还那么,所以JS 的做法是把所有的对象共用的属性全部放在heap堆内存的一个对象(共用属性组成的对象),然后让每一个对象的 __proto__存储这个「共用属性组成的对象」的地址。而这个共用属性,就是传说中的原型
    原型的目的:可以减少不必要的内存浪费
    如:

    var s1 = new String('hi');
    var s2 = new String('he');
    var n1 = new Number(1);
    var n2 = new Number(2);
    var b1 = new Boolean(true);
    var b2 = new Boolean(false);
    var o1 = {
        name: 'xiao',
        age: 6
    }
    var o2 = {
        name: 'ming',
        age: 18
    }
    
    

    根据下面内存图分析原型

    image.png

    图中红色的箭头所连成的线,就组成了一条原型链

    • __proto__就是这些共用属性的引用。
    • 声明Number对象、String对象、Boolean对象时,如声明Number对象,在stack栈内存中存储着该对象的内存地址,对象的内容存储在heap堆内存中。对象的内容里面有__proto__,它指向的Number的共用属性(Number.prototype)。
      某些等式:
    //对象的__proto__指向Object对象的prototype
    obj.__proto__ === Object.prototype
    
    
    //数值的__proto__指向Number对象的共用属性
    n1.__proto__ === Number.prototype;
    
    //Number对象的共用属性的__proto__指向Object对象的共用属性。
    n1.__proto__.__proto__ === Object.prototype;
    
    

    其他对象也可以得出类似的等式

    __proto__ 与 prototype

    image

    当我们写了一句代码var s = new String(' hello ') 以后:

    image

    我们创建的对象的__proto__ 会用来指向原有的String对象,使得我们可以调用String对象的公有属性。

    总结:

    • __proto__是某对象的共用属性的引用,是为了用户使用其共用属性中的方法而存在的 。(使用的)
    • prototype 是浏览器写的,本身就存在,是某对象的共同属性的引用,为了不让对象的共用属性因没有被调用而被垃圾回收而存在。(防止回收)

    一些烧脑的等式

    通过var 对象 = new 函数;推出其他烧脑的等式

    var n = new Number(1);
    //var 对象 = new 函数;
    
    //对象的__proto__最终指向某对象的共用属性,构造某对象的函数的prototype也指向某对象的共用属性
    //__proto__ 是对象的属性,prototype是函数的属性
    对象.__proto__ === 函数.prototype
    
    //函数的prototype是对象,这个对象对应的就是最简单的函数Object
    函数.prototype.__proto__ === Object.prototype
    
    //由于函数本身即是函数(最优先被视为函数),也是对象,而函数的构造函数是Function
    函数.__proto__ === Function.prototype
    
    //Function即是对象,也是函数,但他优先是个函数
    Function.__proto__ === Function.prototype
    
    //Function.prototype也是对象,是普通的对象,所以其对应的函数是Object
    Funciton.prototype.__proto__=== Object.prototype
    
    

    奇葩的Function

    我们经过上面的推导,发现Function,他即是函数,也是对象,所以他有函数的prototype,也有对象的__proto__,即Function.prototype 与Funciton.__proto__互相引用。

    image.png

    注:
    Object.__proto__ === Function.prototype,因为 Function 是 Object 的构造函数。

    相关文章

      网友评论

          本文标题:JS的原型和原型链

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