zoukankan      html  css  js  c++  java
  • 必须知道的 prototype, [[prototype]], __proto__

    首先厘清这三个概念的异同:

    TL;DR
    Prototype是函数专有的属性(对象没有Prototype)(甚至可以说,只有构造函数有“有意义的”Prototype属性),这个属性值指向一个对象。默认的 "prototype" 是一个只有属性 constructor 的对象,属性 constructor 指向函数自身。
    实例对象没有Prototype属性,但可以通过__proto__这个getter/setter来读取对象的[[Prototype]]隐藏属性。这个隐藏属性是设置Object 的 Prototype 的接口

    let a = function() {};
    let b = {};
    
    console.log(a.prototype);      // {constructor: ƒ}
    console.log(b.prototype);      // undefined
    console.log(a.__proto__);      // ƒ ()
    console.log(b.__proto__);      // {constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
    

    [[Prototype]]是一個设置Object 的 Prototype 的接口,是Js对象的一个隐藏属性。它要么是null,要么是一个对象。如果是对象的话,那个对象就是此对象的原型。

    __proto__ 是 [[Prototype]] 的因历史原因而留下来的 getter/setter。__proto__ 的存在是出于历史的原因,现代编程语言建议我们应该使用函数 Object.getPrototypeOf/Object.setPrototypeOf 来取代 __proto__ 去 get/set 原型。但实际上,包括服务端在内的所有环境都支持它,因此我们使用它是非常安全的。

    Prototype是一个对象的属性,prototype 属性是继承成员被定义的地方。Object 之間可以互相成為各自的 Prototype,被繼承的 Object 將會繼承父 Object 的 Prototype 所有屬性。
    原因在于,继承的属性和方法是定义在 prototype 属性之上的(你可以称之为子命名空间 (sub namespace) )——那些以 Object.prototype. 开头的属性,而非仅仅以 Object. 开头的属性。prototype 属性的值是一个对象,我们希望被原型链下游的对象继承的属性和方法,都被储存在其中。于是 Object.prototype.watch()、Object.prototype.valueOf() 等等成员,适用于任何继承自 Object() 的对象类型,包括使用构造器创建的新的对象实例。Object.is()、Object.keys(),以及其他不在 prototype 对象内的成员,不会被“对象实例”或“继承自 Object() 的对象类型”所继承。这些方法/属性仅能被 Object() 构造器自身使用。

    Notes:
    [[Prototype]] Object 內部的特殊屬性,用來將对象写入到 prototype。
    __proto__ 由ES6 開始成為Object的原生屬性,直接對 [[Prototype]] 進行讀寫。
    prototype 是一個Object。如果你要用新建一个对象,那么當 new 一個 instance 時會被用作指向 __proto__作為 instance 繼承的屬性。(let a = new F时,F.prototype就给a的[[Prototype]]赋值。)
    prototype 只存在於 constructor functions,在 instance 上并不存在。相反__proto__則出現在所有对象中。

    "prototype" 属性仅在设置了一个构造函数(constructor function),并通过 new 调用时,才具有这种特殊的影响。
    在常规对象上,prototype 没什么特别的:

    let user = {
      name: "John",
      prototype: "Bla-bla" // 这里只是普通的属性
    };
    

    默认情况下,所有函数都有 F.prototype = {constructor:F},所以我们可以通过访问它的 "constructor" 属性来获取一个对象的构造器。

  • 相关阅读:
    学习笔记之pandas
    学习笔记之Nearest-Neighbour Searching with PostGIS
    学习笔记之Gurobi
    python基础之装饰器
    python作业
    python的位置参数、默认参数、关键字参数、可变参数区别
    python文件处理
    python基础之文件处理
    python基础之条件和循环
    python基础之函数
  • 原文地址:https://www.cnblogs.com/Nullc/p/14493838.html
Copyright © 2011-2022 走看看