__proto__和prototype的区别

简介: `prototype`和`__proto__`虽然都与JavaScript的原型继承和对象关系密切相关,但它们的定义、所属对象、作用和功能等方面存在着明显的区别。理解它们之间的区别对于深入掌握JavaScript的面向对象编程和原型链机制非常重要

在JavaScript中,__proto__prototype是两个用于实现原型继承和对象间关系的重要概念,它们之间存在着一些区别,主要体现在以下几个方面:

定义和所属对象

  • prototypeprototype是函数的一个属性,它指向一个对象,这个对象被称为原型对象。所有通过该函数创建的实例对象,都会共享原型对象上的属性和方法。也就是说,prototype是属于函数的,用于定义通过该函数创建的对象所继承的属性和方法。
  • __proto____proto__是对象的一个内部属性,它指向创建该对象的构造函数的原型对象。当访问一个对象的属性或方法时,如果在对象自身不存在该属性或方法,JavaScript引擎会沿着__proto__属性所指向的原型对象继续查找,以此类推,形成原型链。__proto__是属于对象的,用于在对象查找属性和方法时确定原型链的查找路径。

作用和功能

  • prototype:主要用于实现对象的继承和共享属性方法。通过在函数的prototype属性上定义方法和属性,所有由该函数创建的实例都可以继承这些属性和方法,从而实现代码的复用和对象间的层次关系构建。
  • __proto__:用于在对象查找属性时沿着原型链向上查找,它决定了对象的原型链关系。当对象自身没有某个属性或方法时,通过__proto__找到其原型对象,再在原型对象上查找,直到找到或到达原型链的顶端(Object.prototype.__proto__null)。

示例

function Person() {
   }
Person.prototype.sayHello = function() {
   
  console.log('Hello!');
};

const person1 = new Person();
const person2 = new Person();

console.log(person1.sayHello === person2.sayHello); 
// true,因为person1和person2都继承自Person.prototype,共享sayHello方法

console.log(person1.__proto__ === Person.prototype); 
// true,person1的__proto__指向Person.prototype

function Student() {
   }
Student.prototype = new Person();

const student = new Student();
console.log(student.__proto__ === Student.prototype); 
// true
console.log(student.__proto__.__proto__ === Person.prototype); 
// true,student的原型链为student -> Student.prototype -> Person.prototype -> Object.prototype

可访问性和修改限制

  • prototype:函数的prototype属性是公开可访问和可修改的,可以在任何时候向prototype对象上添加、删除或修改属性和方法。但在修改时需要注意对已创建实例的影响,因为实例会继承prototype上的属性和方法。
  • __proto____proto__属性在现代JavaScript中虽然大部分浏览器都支持直接访问和修改,但它并不是标准的ECMAScript属性,不建议在生产环境中直接修改对象的__proto__属性,因为这可能会导致一些不可预测的结果和性能问题。在一些严格模式下,对__proto__的修改可能会被禁止。

与构造函数和实例的关系

  • prototype:与构造函数紧密相关,它定义了构造函数创建的实例所继承的内容。构造函数通过new关键字创建实例时,实例会自动拥有一个__proto__属性,其值指向构造函数的prototype属性所指向的对象。
  • __proto__:直接体现了实例与构造函数的原型对象之间的关系,通过__proto__可以追溯到实例所继承的原型对象,进而找到构造函数的prototype,以及更上层的原型链。

综上所述,prototype__proto__虽然都与JavaScript的原型继承和对象关系密切相关,但它们的定义、所属对象、作用和功能等方面存在着明显的区别。理解它们之间的区别对于深入掌握JavaScript的面向对象编程和原型链机制非常重要。

相关文章
vue2自定义指令-加载指令v-loading和占位图指令v-showimg
vue2自定义指令-加载指令v-loading和占位图指令v-showimg
|
2月前
|
资源调度 JavaScript Linux
Node.js 编程实战:安装 Node.js 与 npm / yarn
学习 Node.js 前需先正确安装与配置运行环境。推荐使用 LTS 版本,通过 nvm 等工具管理多版本,配合 npm 或 yarn 统一管理依赖。不同系统可采用对应安装方式,安装后验证版本并确保环境变量配置正确,为后续开发打下稳定基础。(238 字)
|
5月前
|
存储 自然语言处理 搜索推荐
从音频与照片生成数字人视频:阿里云百炼工作流打造“超级数字人”全流程解析
阿里云百炼上线通义万相2.2数字人视频生成模型S2V,支持音频+单张人像生成个性化数字人视频。结合Qwen-TTS、Qwen-Image与IMS智能剪辑,打造从内容生成到视频输出的全自动“超级数字人”工作流,大幅提升制作效率与质量。
1644 2
|
8月前
|
前端开发 JavaScript 开发者
2025 最新 100 道 CSS 面试题及答案解析续篇
本文整理了100道CSS面试题及其答案,涵盖CSS基础与进阶知识。内容包括CSS引入方式、盒模型、选择器优先级等核心知识点,并通过按钮、卡片、导航栏等组件封装实例,讲解单一职责原则、样式隔离、响应式设计等最佳实践。适合前端开发者巩固基础、备战面试或提升组件化开发能力。资源地址:[点击下载](https://pan.quark.cn/s/50438c9ee7c0)。
168 5
2025 最新 100 道 CSS 面试题及答案解析续篇
|
JSON 前端开发 JavaScript
不会webpack的前端可能是捡来的,万字总结webpack的超入门核心知识
该文章提供了Webpack的基础入门指南,涵盖安装配置、基本使用、加载器(Loaders)、插件(Plugins)的应用,以及如何通过Webpack优化前端项目的打包构建流程。
不会webpack的前端可能是捡来的,万字总结webpack的超入门核心知识
|
消息中间件 存储 监控
消息中间件第八讲:消息队列 RocketMQ 版实战、集群及原理
消息中间件第八讲:消息队列 RocketMQ 版实战、集群及原理
903 0
|
安全 API C#
C# 如何让程序后台进程不被Windows任务管理器强制结束
C# 如何让程序后台进程不被Windows任务管理器强制结束
699 0
|
存储 JavaScript 前端开发
操作document.cookie存储和读取Cookies
操作document.cookie存储和读取Cookies
1032 2
|
存储 NoSQL 关系型数据库
何时使用MongoDB而不是MySql
MySQL 和 MongoDB 是两个可用于存储和管理数据的数据库管理系统。MySQL 是一个关系数据库系统,以结构化表格格式存储数据。相比之下,MongoDB 以更灵活的格式将数据存储为 JSON 文档。两者都提供性能和可扩展性,但它们为不同的应用场景提供了更好的性能。
650 1
何时使用MongoDB而不是MySql
|
JavaScript 前端开发
[Vue warn]: Error in v-on handler (Promise/async): “NavigationDuplicated: Navigating to current loca
[Vue warn]: Error in v-on handler (Promise/async): “NavigationDuplicated: Navigating to current loca
561 0