美文网首页
JS对象中的[[Prototype]]、__proto__、pr

JS对象中的[[Prototype]]、__proto__、pr

作者: 奋斗_登 | 来源:发表于2023-03-12 14:05 被阅读0次
    1. 对象

    ECMA-262将对象定义为一组属性的无序集合。对象的每个属性或者方法都有一个名称来标识,这个名称映射到一个值。可以把对象想象成一张散列表,其中的内容就是一组键/值对,值可以是数据或者函数。

    2. [[Prototype]] 是什么

    ECMA-262使用一些内部特性来描述属性的特征。这些特性是由为JavaScript实现引擎的规范定义的。因此,开发者不能在JavaScript中直接访问这些特性。
    为了将某个特性标识为内部特性,规范会用两个中括号把特性的名称括起来,比如[[Prototype]]、[[Enumerable]]等。
    [[Prototype]]就是这个一个内部属性 , 它指的是对象的原型
    脚本中没有访问这个[[Prototype]]特性的标准方式,但Firefox、Safari和Chrome会在每个对象上暴露__proto__属性,通过这个属性可以访问对象的原型

    Prototype
    3. 原型

    任何对象都有原型,原型也是一个对象,其他对象可以通过它实现集成,每个原型自身又有一个原型,直到最顶端的Object。
    __proto__属性为实例指向原型对象的指针,每个对象多有这个属性。
    如下图所示,product的原型为Object,Object的原型是null,因为Object为原型链的顶端

    let product = {
         name: '笔记本',
         price: 5999
    }
    
    原型
    4. prototype

    每个函数(对象上没有prototype属性)都会创建一个prototype属性,被称为原型对象,这个属性是一个对象,包含应该由特定引用类型的实例共享的属性和方法。实际上,这个对象就是通过调用构造函数创建的对象的原型。使用原型对象的好处是,在它上面定义的属性和方法可以被对象实例共享。

    function Person() {}
    Person.prototype.name = "Nicholas";
    Person.prototype.age = 29;
    Person.prototype.job = "Software Engineer";
    Person.prototype.sayName = function() {
      console.log(this.name);
    };
    
    let person1 = new Person();
    person1.sayName(); // "Nicholas"
    
    let person2 = new Person();
    person2.sayName(); // "Nicholas"
    
    console.log(person1.sayName == person2.sayName); // true
    
    prototype
    5. constructor

    constructor属性始终指向创建当前对象的构造函数,任何一个对象都有constructor属性,指向创建这个对象的构造函数。
    constructor 原型对象中包含这个属性,实例当中也同样会继承这个属性
    默认情况下,所有原型对象自动获得一个名为constructor的属性,指回与之关联的构造函数。Person.prototype.constructor指向Person。然后,因构造函数而异,可能会给原型对象添加其他属性和方法。

    constructor
    6. 原型链

    每个构造函数都有一个原型对象,原型有一个属性指回构造函数,而实例有一个内部指针指向原型。如果原型是另一个类型的实例呢?那就意味着这个原型本身有一个内部指针指向另一个原型,相应地另一个原型也有一个指针指向另一个构造函数。这样就在实例和原型之间构造了一条原型链。这就是原型链的基本构想。

    function SuperType() {
        this.property = true;
    }
    
    SuperType.prototype.getSuperValue = function () {
        console.info(this.property);
        return this.property;
    }
    
    function SubType() {
        this.subproperty = false;
    }
    
    SubType.prototype = new SuperType();
    SubType.prototype.getSubValue = function () {
        console.info(this.subproperty);
        return this.subproperty;
    }
    
    let subTypeInstance = new SubType();
    subTypeInstance.getSubValue(); //false
    

    默认情况下,所有引用类型都继承自Object,这也是通过原型链实现的。任何函数的默认原型都是一个Object的实例,这意味着这个实例有一个内部指针指向Object.prototype。这也是为什么自定义类型能够继承包括toString()、valueOf()在内的所有默认方法的原因。

    相关文章

      网友评论

          本文标题:JS对象中的[[Prototype]]、__proto__、pr

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