百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

不会js中原型、原型链与constructor到底是什么?

myzbx 2025-07-23 16:44 20 浏览

关注我:知码前端,获取更多前端知识~~~

前言

哇呀呀~我说寒山说哭 我带你出 我敬滴酒带你出 我欲成冰再也无退路 怎舍寒冰冰冻我心哭~~~

Hello,广大的前端小伙伴们,又到了写文章的时候,我们说一下在javascript中一个比较重要的知识点,也是一个比较难理解的知识点,可以这么说如果学javascript这门语言不学会这个知识,那只能说学的没点意思~~那我们来说一下到底要讲什么知识呢----原型

要讲原型我们得分几个点讲解一下:

  • 为什么要有原型
  • 原型是什么
  • 原型链是什么
  • __propo__、prototype、contstructor这三个属性是什么

该篇文章可能会比较长,也可能会比较难懂,希望小伙伴们耐心,多看几次,好好理解~相信大家一定会学会这个知识点。

为什么要有原型

我们知道js中对象是通过构造函数来创建是,有的小伙伴可能要开始怼了,我创建对象的时候就没有用构造函数:

// 我直接通过字面量的方法来创建一个对象,而没有构造函数
const person = {}
// 其实上面代码也可以写成下面的
const person = new Object()
// 这两个写法是等价的

那么我们通过构造函数来创建一个对象,就可以把对象的一些属性和方法直接写到函数里面:

function Person(name, age) {
  this.name = name
  this.age = age
}
const person = new Person('知码', 20)
console.log(person.name) // '知码'
console.log(person.age) // '知码'

这样写是没有问题的,但是会有一个缺点:用一个构造函数来创建的实例之间,无法共享属性。从而导致系统的资源浪费。我们对每个实例添加一个方法:sayHello

function Person(name, age) {
  this.name = name
  this.age = age
  this.sayHello = function () {
    console.log('hello,' + this.name)
  }
}
const person1 = new Person('知码', 20)
const person2 = new Person('前端', 30)
console.log(person1.sayHello === person2.sayHello) // false

上面代码创建的两个实例都有相同的属性:name、age、sayHello。对于name和age来说是可以的,各自一份。但对于sayHello这个方法,有会浪费系统资源,因为没有必要两个实例都有这个方法。换句话说,每个实例之间应该共享这个方法。

为了解决这个问题,js就提供了原型对象(prototype)这个对象。

原型是什么

原型就是一个对象,然后用prototype这个变量来引用。每个function函数在被创建的时候都会有这个属性。(这里注意一下,只有用function声明的函数才会有这个属性,而用箭头函数是没有的。)当函数被普通调用的时候,这个对象是没有什么作用的。但当函数被当成构造函数使用的时候,这个属性就是每个实例的原型对象。在这个对象上创建的属性和方法都可以在每个实例之间共享。如:

function Person(name, age) {
  this.name = name
  this.age = age
}
Person.prototype.address = '北京'
const person1 = new Person('知码', 20)
const person2 = new Person('前端', 30)
person1.address // '北京'
person2.address // '北京'
// 可以看出`address`这个属性可以被两个实例共享

// 如果改变了这个`address`值,那么每个对象也会改变
Person.prototype.address = '上海'
person1.address // '上海'
person2.address // '上海'

可能有的小伙伴会问了,没有在函数中定义address这个属性呀,为什么实例对象会访问到呢?

如果实例对象身上有某个属性或者方法,那么会优先调用自身的,如果在自身上没有找到,就会到原型对象上去找。

对于address我们确定是没有在函数内定义,但是在Person函数的原型上定义了,所以实例对象就会按上述规则去找,最终找到address这个属性了。

原型链是什么

上面说道原型就是一个对象,在javascript中每个对象都可以充当一个原型对象,而每个对象都有自己的原型对象。就这样:

对象---->原型对象---->原型对象上的原型对象----> ...---->Object.prototype---->null

最终会到Object上的原型对象。这就是原型链。原型链的尽头就是null

当某个对象要访问某个属性或者方法的时候,就会按这个链去找,如果自身或者从某个原型上找到了属性,就不会再继续往下查找,直接返回。如果都没有所有的原型对象都没有找到这个属性,就返回undefined。举个例子说一下:

function Person(name, age){
  this.name = name
  this.age = age
}
Person.prototype.address = '北京'
const person = new Person('知码', 20)
person.name // '知码'
person.address // '北京'
person.toString() // [object Object]
person.height // undefined
  • 对于name属性来说,每个实例都有这个属性,所以会访问到,不会去原型或者原型链上查找。
  • 对于address属性来说,自身是没有这个属性,就会去函数的原型对象上去找,结果找到了,就直接返回
  • 对于toString方法来说,自身上没有这个方法,构造函数的原型对象上也没有,直到查找到Object.protptype的原型对象上,结果找到了,就会执行这个方法。
  • 对于height这个属性来说找了所有的原型对象也没有找到,就返回undefined
  • 或许又有小伙伴要问了,对于实例对象来说,它怎么知道去原型对象上去查找自身没有的属性或者方法呢?或者说他是通过什么样的机制去查找呢?这就用到下面要说的__proro__、prototype、constructor这三者的关系了。

    __propo__、prototype、contstructor这三个属性是什么

    如果你能看这到里说明你对原型和原型链有一个比较客观的认识。接下来的内容可能比较难懂,再坚持一下

    __proto__

    __proto__是前后两个下划线_ _,不是一个整体的下划线。

    当我们在创建一个对象的时候,系统都会给这个对象创建一个额外的属性__proto__,这个属性就是指向的构造函数中的原型对象。它是实例对象独有的。所以通过它就能访问到了函数原型对象。

    function Person(name, age){
      this.name = name
      this.age = age
    }
    const person = new Person('知码', 20)
    person.__proto__ === Person.prototype // true
    //两者都是指向同一个对象

    prototype

    前面也提过这个属性,它是function函数独有的。指向一个对象。

    constructor

    这个属性是prototype对象的一个属性,也就是说每个函数原型对象默认都会有这个属性,它指向了构造函数本身。

    用一个句话描述一下这三个对象之间的关系:

    每个实例对象都有__proto__属性,指向着构造函数的原型对象prototype,prototype对象里面有一个属性constructor属性,指向着构造函数本身。

    好了,今天先介绍这么多,下节我们细说下这三个属性。

    关注我:知码前端,获取更多前端知识~~~

    相关推荐

    OPPO Find X9手机曝料:6.6英寸屏幕、天玑9500芯片

    IT之家8月27日消息,科技媒体xpertpick今天(8月27日)发布博文,报道称OPPO计划于今年10月推出FindX9系列旗舰手机,其中包括FindX9和...

    OPPO Find X9系列搭载影像新硬件,支持Ultra级画质和色彩还原

    IT之家8月27日消息,OPPOFindX9系列手机发布时间逐渐临近,目前官方已开启新机的前瞻预热。OPPOFind系列产品负责人周意保今日发文解释了厂商为什么现在都喜欢跨界合作这一...

    我回来了!聊聊屏幕对续航的影响_屏幕耗电吗

    时隔一周终于回国,让大家久等了本来上周日就能到家,结果在旧金山转机的时候把护照弄丢了…幸好后来被一位黑人大姐找到了,才能顺利回国,感谢勤劳朴实的美利坚人民。出差途中笔记本的续航是很重要的,刚好联想的产...

    J人福音、P人救星,Lumix Flow如何重塑专业视频拍摄工作流

    “等一下,刚才那个中景拍了没有?”“A机位的素材是哪一场的?”“完了,我忘了记哪一条是最好的了!”“今晚加个班,先把能用的素材挑出来……”作为经常一个人拍视频的内容创作者,这种崩溃称得上习以为常。如果...

    realme史上最窄边框和下巴 realme GT Neo3正式发布

    中关村在线消息:今天下午14点,realme召开真我GTNeo3发布会。realmeGTNeo3搭载6.7英寸2412×1080OLED直屏,其支持120Hz刷新率,360Hz触控采样率,智能...

    用酒精擦屏幕,对屏幕的伤害有多大?

    天府新青年你触手可及的朋友圈附录:1.不是所有电脑的屏幕都不能用酒精来擦,通常来说只有镜面屏屏幕才有涂层,这种不能用酒精擦;而雾面屏用的是另外一种抗反射技术,这种一般擦了没事。镜面屏和雾面屏特别好认...

    windows11截屏快捷键是哪个?windows11快捷键设置大全

    windows11键盘快捷方式就是键盘快捷方式就是按键或按键组合,可提供一种替代方式来执行通常使用鼠标执行的操作。下面就来分享下windows11截屏快捷键是哪个和windows11快捷键设置大全。一...

    三星Galaxy S25 Slim配置曝光 6.7英寸屏幕搭配2亿像素主摄

    【CNMO科技新闻】三星GalaxyS25系列将于北京时间1月23日正式发布,CNMO注意到有博主爆出了即将亮相GalaxyS25Slim的配置信息。据悉,GalaxyS25Slim将配备一...

    两种手机屏幕到底有什么不一样?哪种手机屏幕更好?

    一般来说,我们的手机屏幕只分为两种OLED和LCD,LCD是大火的一种手机屏幕,是千元机以及高端机的标配,OLED算是后起之秀,是近几年才渐渐兴起的一种类型的手机屏幕,那么这两种手机屏幕到底有什么不一...

    有强芯才好用 这三款高性价比旗舰芯热机最低仅需1799元

    在选购手机时,相信大家肯定都会把性能作为考虑的重点之一。而如果希望拥有出色的性能表现,一颗旗舰处理器是必不可少的。今天我就为大家汇总了几款采用旗舰处理器的底价新机,感兴趣的朋友千万不要错过。moto...

    一文搞定FastDFS的搭建和使用_fastdfs怎么样

    1.FastDFS概述FastDFS是一个开源的轻量级分布式文件系统,它对文件进行管理,功能包括:文件存储、文件同步、文件访问(文件上传、文件下载)等,解决了大容量存储和负载均衡的问题。特别适合以文...

    涨姿势!超级计算机用啥文件系统呢?

    2015-10-1705:58:00作者:赵为民在计算机中,文件系统(filesystem)是一个非常重要的组件,你可以将他看做是操作系统的子系统,其实质就是一种软件的组件,通过文件系统我们可以...

    Window as a VM:Chrome OS 现可窗口化运行其它 Linux 分支

    这世上纵然有多种办法可以在Chromebook上安装运行ChromeOS和其它Linux分支多系统,但如果无需重启通过引导切换,确实是个很酷的改进。Google布道师Francois...

    Win10新预览版19577开始推送:新图标+多项新功能

    今日凌晨,微软正式向Windows10Insider快速通道用户推送了全新版本Windows10——Windows10InsiderPreviewBuild19577。19577版本是...

    微软Windows升级密钥(例如家庭版升级为企业版)

    下面的密钥,是微软官方提供的,仅能用于Windows10系统版本的升级,比如从家庭版升级为专业版、专业版升级为企业版等。升级密钥不能用于激活系统,激活需要KMS或者数字权利,由于涉及到版权问题,在此不...