彻底搞懂JS原型:_ _ proto _ _与prototype的区别到底在哪?

无数JavaScript开发者在初学面向对象时,都曾被 _ _ proto _ _ 和 prototype 这对"双胞胎"搞得晕头转向。看着控制台里层层嵌套的指向箭头,不禁灵魂发问:它们到底有啥区别?为什么一个对象上既有没有下划线的 prototype,又有带双下划线的 _ _ proto _ _?其实,这两个概念之所以让人困惑,是因为我们总试图把它们当成孤立的知识点去死记硬背。事实上,它们是JavaScript实现原型继承这枚"硬币"的正反面:一个是基因的提供者,一个是基因的传递者。今天,我们就来彻底扒开这层迷雾,让你再也不用在这两个词之间反复横跳!

原型 : prototype (显示原型)

  1. 函数天生拥有的一个属性
  2. 我们可以将一些属性和方法挂载在原型上,在创建实例之后,实例就可以调用这些属性和方法
javascript 复制代码
Array.prototype.abc = function (){
    console.log('abc');
}

arr.abc()

const arr =[]     //new Array()
arr.unshift(1)
  1. 我们也可以将一些公用的属性和方法添加在原型上,减少构造函数在执行时的性能开销
ini 复制代码
Car.prototype.name = 'bmw'
Car.prototype.long= 4888
Car.prototype.height = 1400

function Car(color){
    this.color = color
}

const car = new Car('blue')
console.log(car);
console.log(car.name);  // bmw
  1. 实例对象无法修改原型上的属性值
arduino 复制代码
car.name= 'audi'
console.log(car.name);    // audi
console.log(car.__proto__);  // name = 'bmw'  long= 4888   height = 1400
  • 实例对象中显示拥有的属性 来自于 构造函数中定义的属性
  • 实例对象中隐示拥有的属性 来自于 构造函数的原型上

对象原型: _ _ proto _ _ (隐式原型)

  1. 每个对象天生都拥有_ _ proto _ _属性,该属性也是一个对象
  2. V8 在访问对象中的一个属性时,会先访问显示存在的属性,如果没有,就会去对象的隐示原型上查找
javascript 复制代码
Person.prototype.say = function () {
    console.log('我是大帅哥');
}
function Person() {
    this.name = '猪猪侠'
}

const p = new Person()    // p.__proto__ === Person.prototype
p.say()
  1. 实例对象的隐示原型 === 构造函数的显示原型 4. constructor 构造器属性,记录该实例对象是由谁构建的

原型链

V8 在访问对象中的一个属性时,会先访问显示存在的属性,如果没有,就会去对象的隐示原型上查找,如果还没找到,就会顺着隐示原型一直往上找,直到找到 null 为止,这个查收关系,就叫原型链查找

Object.prototype._ _ proto _ _ = null

javascript 复制代码
Grand.prototype.house = function () {
  console.log('汤臣一品');
}

function Grand (){
  this.card = 10000000
}
Father.prototype = new Grand()     // {card: 10000000}
function Father() {
  this.lastName = '张'
}
Child.prototype = new Father()     // {lastName: '张'}
function Child() {
  this.age = 18
}
                         // new Object()     
const p = new Child() 
console.log(p.lastName); 
p.house();

根据上图我们可以充分了解原型链之间的关系即以下内容:

const f1 = new Foo()

  1. f1._ _ proto _ _ = Foo.prototype

  2. Foo.prototype._ _ proto _ _ = Object.prototype

  3. Object.prototype._ _ proto _ _ = null

  4. Foo._ _ proto _ _ = Function.prototype

  5. Function.prototype._ _ proto _ _ = Object.prototype

  6. Function._ _ proto _ _ = Function.prototype

总结

prototype 是设计图纸,_ _ proto _ _ 是建造好的通道。当你不再孤立地看它们,而是把它们当成实例与构造函数之间的那根"红线",JS的原型世界,便再无秘密。我们下期在见!

相关推荐
anOnion12 小时前
Agentic 前端开发之 实时显示 AI Agent 终端输出
前端·javascript·人工智能
这是个栗子12 小时前
【前端性能优化】优化数据加载:用 Promise.all 从串行到并行
前端·javascript·性能优化·异步编程·前端优化·promise.all
fei_sun13 小时前
黑洞路由(Null Route/空接口路由)
服务器·前端·javascript
摇滚侠14 小时前
方法 A 等方法 B 执行完再执行 叫同步调用还是异步调用 JS 默认是同步调用还是异步调用
开发语言·javascript·ecmascript
触底反弹15 小时前
🔥 字符串算法面试三连击:反转、回文、回文变种,搞懂这三题稳了!
前端·javascript·算法
触底反弹15 小时前
AI Tool Use 深度解析:大模型是如何"突破物理限制"调用外部工具的?
javascript·人工智能·后端
竹林81815 小时前
从 RPC 超时到批量签名:我用 @solana/web3.js 重构了一个 NFT 铸造页面,踩了这些坑
前端·javascript
优雅格子衫16 小时前
TypeScript 类的基本使用小结
javascript·ubuntu·typescript
橘子星16 小时前
从零手写 RAG 语义检索:基于 Node.js 实现轻量级向量搜索
javascript·人工智能
林希_Rachel_傻希希16 小时前
web性能优化之————图片效果
前端·javascript·面试