当前位置: 首页 > news >正文

__proto__ 和 prototype的关系

图片描述

__proto__ 和 prototype的关系


先上答案:

​ 对象上都有__proto__属性(函数也是对象)

​ 一般情况下对象的__proto__属性指向该对象的构造函数的原型对象。

​ 函数上才有prototype属性,该属性指向该函数的原型对象。

OK,下面来详细解释一下

什么是__proto__

这个其实是一个 internal slot (翻译成内置槽?),叫做 [[ prototype ]] ,也称为隐式原型。在js里所有的普通对象都会有。它的值要么是 null(原型链的最终), 要么还是一个对象。

之前并没有一个标准的方法来访问这个值,但是大多数浏览器都支持通过用.__proto__来得到它的值。所以 [[ prototype ]] 就被叫成了 __proto__ 。直到ES5中增加了标准的方法 :Object.getPrototypeOf()

All ordinary objects have an internal slot called [[Prototype]]. The value of this internal slot is either null or an object and is used for implementing inheritance.

ECMAScript Language Specification

什么是prototype

所有用 function 语句、函数字面量或者 Function 构造函数定义的函数都会同时自动创建一个 prototype 属性,指向该函数的原型对象。

另外,通过Function.prototype.bind()创建的函数没有 prototype 属性。

NOTE 1 Function objects created using Function.prototype.bind are exotic objects. They also do not have a prototype property.

ECMAScript Language Specification

这里 Function 的 prototype 有点不同,实际上它是内部对象%FunctionPrototype%,它本身是一个内置函数对象。

它有一些特殊的规则,比如 Function.prototype.length === 0 等

The Function prototype object is the intrinsic object %FunctionPrototype%. The Function prototype object is itself a built-in function object. When invoked, it accepts any arguments and returns undefined. It does not have a [[Construct]] internal method so it is not a constructor.

NOTEThe Function prototype object is specified to be a function object to ensure compatibility with ECMAScript code that was created prior to the ECMAScript 2015 specification.

The value of the [[Prototype]] internal slot of the Function prototype object is the intrinsic object %ObjectPrototype% (19.1.3). The initial value of the [[Extensible]] internal slot of the Function prototype object is true.

The Function prototype object does not have a prototype property.

The value of the length property of the Function prototype object is 0.

The value of the name property of the Function prototype object is the empty String.

ECMAScript Language Specification

Object 的 prototype 也有一点不一样,它其实是内部对象%ObjectPrototype%,它本身是一个普通对象。

做为对象它的 __proto__ 也就是 [[prototype]] 值为 null 。

Object.prototype上挂载着valueOf,toString等方法。

The Object prototype object is the intrinsic object %ObjectPrototype%. The Object prototype object is an ordinary object.

The value of the [[Prototype]] internal slot of the Object prototype object is null and the initial value of the [[Extensible]] internal slot is true.

ECMAScript Language Specification

两者的关系

先上一张神图 :

图片描述

每个被构造函数创建出来的对象都有一个隐式引用,指向其构造函数的prototype属性的值。此外,一个原型可能对它的原型有一个非空的隐式引用,以此类推,就叫做原型链。

Every object created by a constructor has an implicit reference (called the object’s prototype) to the value of its constructor’s "prototype" property. Furthermore, a prototype may have a non-null implicit reference to its prototype, and so on; this is called the prototype chain. When a reference is made to a property in an object, that reference is to the property of that name in the first object in the prototype chain that contains a property of that name. In other words, first the object mentioned directly is examined for such a property; if that object contains the named property, that is the property to which the reference refers; if that object does not contain the named property, the prototype for that object is examined next; and so on.

ECMAScript Language Specification

看图说话

构造函数 Foo 的原型属性 prototype 指向了原型对象 Foo.prototype 。f1, f2 是Foo的实例,通过指向原型对象的__proto__ 就可以继承原型对象上公有的方法。同时,Foo.prototype 上constructor 属性指回 构造函数 Foo。

构造函数Foo本身也是对象,所以也有 __proto__ ,指向了Foo的构造函数的原型对象,也就是Function.prototype。

原型对象也是对象,所以也有 __proto__ ,指向Object.prototype。最终Object.prototype.__proto__指向 null。

(完) :)

相关文章:

  • 这道js题你会吗?
  • java B2B2C源码电子商城系统-Spring Cloud Eureka自我保护机制
  • 基于 React TypeScript Webpack 的微前端应用模板
  • xgboost回归损失函数自定义【一】
  • Java null最佳实践
  • 36氪首发|「优仕美地医疗」获亿元级B轮融资,要打造日间手术机构的连锁服务网络...
  • 阿里云联合8家芯片商推“全平台通信模组”,加速物联网生态建设
  • MySQL设置主从复制
  • 赶紧收藏!新鲜出炉的重庆轨道交通图 首末班时间和线路都在里面
  • 厉害!重庆参加马拉松赛人数7年翻10倍,今年区县马拉松赛事将大增
  • python教程(一)·命令行基本操作
  • TCP三次握手四次挥手
  • C++类中的特殊成员函数
  • ES搜索引擎集群模式搭建【Kibana可视化】
  • spring cloud gateway 源码解析(4)跨域问题处理
  • canvas 五子棋游戏
  • Java超时控制的实现
  • JAVA多线程机制解析-volatilesynchronized
  • JS 面试题总结
  • magento 货币换算
  • nfs客户端进程变D,延伸linux的lock
  • react-core-image-upload 一款轻量级图片上传裁剪插件
  • Vue组件定义
  • 每个JavaScript开发人员应阅读的书【1】 - JavaScript: The Good Parts
  • 如何编写一个可升级的智能合约
  • 扫描识别控件Dynamic Web TWAIN v12.2发布,改进SSL证书
  • 深入浏览器事件循环的本质
  • 腾讯优测优分享 | 你是否体验过Android手机插入耳机后仍外放的尴尬?
  • 协程
  • 学习笔记:对象,原型和继承(1)
  • 因为阿里,他们成了“杭漂”
  • ​软考-高级-系统架构设计师教程(清华第2版)【第9章 软件可靠性基础知识(P320~344)-思维导图】​
  • ​一、什么是射频识别?二、射频识别系统组成及工作原理三、射频识别系统分类四、RFID与物联网​
  • # 手柄编程_北通阿修罗3动手评:一款兼具功能、操控性的电竞手柄
  • #我与Java虚拟机的故事#连载01:人在JVM,身不由己
  • %3cli%3e连接html页面,html+canvas实现屏幕截取
  • (pojstep1.1.1)poj 1298(直叙式模拟)
  • (翻译)Entity Framework技巧系列之七 - Tip 26 – 28
  • (附源码)springboot优课在线教学系统 毕业设计 081251
  • (三)模仿学习-Action数据的模仿
  • (三十五)大数据实战——Superset可视化平台搭建
  • .NET CORE 2.0发布后没有 VIEWS视图页面文件
  • .NET/C# 获取一个正在运行的进程的命令行参数
  • .NET版Word处理控件Aspose.words功能演示:在ASP.NET MVC中创建MS Word编辑器
  • .net经典笔试题
  • .NET连接数据库方式
  • .stream().map与.stream().flatMap的使用
  • /etc/X11/xorg.conf 文件被误改后进不了图形化界面
  • @Autowired和@Resource的区别
  • @Bean有哪些属性
  • @FeignClient 调用另一个服务的test环境,实际上却调用了另一个环境testone的接口,这其中牵扯到k8s容器外容器内的问题,注册到eureka上的是容器外的旧版本...
  • @拔赤:Web前端开发十日谈
  • [ 云计算 | AWS ] 对比分析:Amazon SNS 与 SQS 消息服务的异同与选择
  • [<MySQL优化总结>]
  • [2023-年度总结]凡是过往,皆为序章