原型链是什么?五分钟教会你

了解原型链之前,先来了解一下什么是原型

原型

原型主要分为显示原型和隐式原型

  • 显示原型:prototype
  1. 函数天生就拥有的一个属性
  2. 我们可以将一些属性和方法挂载在原型上;在创建实例之后,实例就可以调用这些属性和方法
  3. 我们也可以将一些公用的属性和方法添加在原型上,减少构造函数在执行时的性能开销
  4. 实例对象不能修改原型上的属性值
js 复制代码
function Car(color){
this.name='su7'
this.lang='4800'
this.height=1400
this.color=color
}
const car=new Car('blue')
console.log(car)//Car { name: 'su7', lang: '4800', height: 1400, color: 'blue' }

可以看到,v8在执行这段函数的时候,把第2、3、4行这些默认的东西都给执行了,如果我们创建car1,car2,car3...的时候,每次都要重复执行这几行代码,这会大大增加v8的运行效率,所以我们要用到原型,将Car作为car的原型

js 复制代码
Car.prototype.name='su7'
Car.prototype.lang=4800
Car.prototype.height=1400
function Car(color){
this.color=color
}
const car=new Car('blue')
car.name='yu7'
console.log(car.name)//yu7
console.log(Car.prototype)//{ name: 'su7', lang: 4800, height: 1400 }
console.log(car)//Car { color: 'blue', name: 'yu7' }

可以看到,把Car作为原型之后,可以大大省去v8的执行时间,就算创建再多的car都不用次次都执行名字长度高度,而且就算把对象中的名字改掉,原型当中的名字也不会改变

  • 实例对象中显示拥有的属性 来自于 构造函数中定义的属性
  • 实例对象中隐式拥有的属性 来自于 构造函数的原型上
  • 隐式原型:proto
  1. 每个对象都拥有__proto__属性,该属性也是一个对象
  2. v8 在访问对象中的一个属性时,会先访问对象中显示存在的属性,如果没有,就会去对象的隐式原型上查找
  3. 实例对象的隐式原型 === 构造函数的显示原型
  4. constructor 构造器属性,记录该实例对象是由谁创建的
js 复制代码
Person.prototype.say=function(){
console.log('123')//②在Person.prototype中找到了say()
}
function Person(){
this.name='强哥'
}
const p=new Person()//p.__proto__=Person.prototype
p.say()//123   ①发现p中找不到say,就去p的隐式原型中找 ③Persone.prototype有say(),就可以输出123了

这①②③的步骤也就是接下来要讲的原型链了

原型链

简单来说:每一个对象都有自己的隐式原型,如果在隐性原型中找不到目标,就会去它的隐性原型中的显性原型中寻找(隐性原型也是一个对象),一路向上直到找到null

js 复制代码
Grand.prototype.house=function(){
  this.house='汤臣一品'
}
function Grand(){
   this.card=1000000
}
Father.prototype=new Grand
function Father() {
  this.lastName = '张'
}
Child.prototype=new Father
function Child() {
  this.age = 18
}
const p = new Child()
p.house()
console.log(p.house)//汤臣一品
console.log(p.car)//undefined此时执行的是p.__proto__=Child.prototype=Child.__proto__=Object.prototype=null

原型链主要分为以下几种情况

js 复制代码
function Foo()
let f1 = new Foo();
f1.__proto__ = Foo.prototype; 
Foo.prototype.__proto__ = Object.prototype; //Foo.prototype本质也是普通对象
Object.prototype.__proto__ = null; // 原型链到此停止

------------------------------------------------------------我是分割线---------------------------------------------------------

js 复制代码
Foo.__proto__=Function.prototype
Function.prototype.__proto__=Object.prototype

------------------------------------------------------------我是分割线---------------------------------------------------------

js 复制代码
Function.__proto__=Function.prototype

最后供上一张经典图方便理解

相关推荐
mayaairi5 小时前
JS循环语句深度解析:嵌套for、while与do...while
开发语言·前端·javascript
To_OC5 小时前
啃完流式输出:从一个卡顿的 LLM 接口开始,我搞懂了数据流到底怎么 “流”
前端·javascript·llm
海上彼尚9 小时前
Nodejs也能写Agent - 22.LangGraph篇 - 上下文工程
前端·javascript·人工智能·langchain·node.js
默_笙10 小时前
🎉 AI 项目里为什么需要 BFF?因为我实在不想在前端处理二进制流
前端·javascript
xyphf_和派孔明12 小时前
企业级微前端项目完整创建步骤,第三步:配置 Vue 子应用
前端·javascript
路光.14 小时前
Vue2升级Vue3处理原 UMD/CommonJS 打包文件,不是标准 ESM
前端·javascript·vue.js·vue3
一只月月鸟呀15 小时前
移动端tap与click的区别 && 点透事件
开发语言·前端·javascript
KaMeidebaby15 小时前
卡梅德生物技术快报|抗体筛选:抗体筛选中的噬菌体展示四参数调优——从流程设计到数据验证
开发语言·前端·javascript
默_笙16 小时前
🔑 让 AI 学会"读"网页:我用 Cheerio 爬了一篇掘金文章,然后切成小块存进了向量库
前端·javascript
方方洛16 小时前
AI 教程系列-TUI 应用开发教程14-技能系统与可扩展性
前端·javascript·typescript