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

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

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

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

前言

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

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属性,指向着构造函数本身。

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

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

    相关推荐

    如何设计一个优秀的电子商务产品详情页

    加入人人都是产品经理【起点学院】产品经理实战训练营,BAT产品总监手把手带你学产品电子商务网站的产品详情页面无疑是设计师和开发人员关注的最重要的网页之一。产品详情页面是客户作出“加入购物车”决定的页面...

    怎么在JS中使用Ajax进行异步请求?

    大家好,今天我来分享一项JavaScript的实战技巧,即如何在JS中使用Ajax进行异步请求,让你的网页速度瞬间提升。Ajax是一种在不刷新整个网页的情况下与服务器进行数据交互的技术,可以实现异步加...

    中小企业如何组建,管理团队_中小企业应当如何开展组织结构设计变革

    前言写了太多关于产品的东西觉得应该换换口味.从码农到架构师,从前端到平面再到UI、UE,最后走向了产品这条不归路,其实以前一直再给你们讲.产品经理跟项目经理区别没有特别大,两个岗位之间有很...

    前端监控 SDK 开发分享_前端监控系统 开源

    一、前言随着前端的发展和被重视,慢慢的行业内对于前端监控系统的重视程度也在增加。这里不对为什么需要监控再做解释。那我们先直接说说需求。对于中小型公司来说,可以直接使用三方的监控,比如自己搭建一套免费的...

    Ajax 会被 fetch 取代吗?Axios 怎么办?

    大家好,很高兴又见面了,我是"高级前端进阶",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!今天给大家带来的主题是ajax、fetch...

    前端面试题《AJAX》_前端面试ajax考点汇总

    1.什么是ajax?ajax作用是什么?AJAX=异步JavaScript和XML。AJAX是一种用于创建快速动态网页的技术。通过在后台与服务器进行少量数据交换,AJAX可以使网页实...

    Ajax 详细介绍_ajax

    1、ajax是什么?asynchronousjavascriptandxml:异步的javascript和xml。ajax是用来改善用户体验的一种技术,其本质是利用浏览器内置的一个特殊的...

    6款可替代dreamweaver的工具_替代powerdesigner的工具

    dreamweaver对一个web前端工作者来说,再熟悉不过了,像我07年接触web前端开发就是用的dreamweaver,一直用到现在,身边的朋友有跟我推荐过各种更好用的可替代dreamweaver...

    我敢保证,全网没有再比这更详细的Java知识点总结了,送你啊

    接下来你看到的将是全网最详细的Java知识点总结,全文分为三大部分:Java基础、Java框架、Java+云数据小编将为大家仔细讲解每大部分里面的详细知识点,别眨眼,从小白到大佬、零基础到精通,你绝...

    福斯《死侍》发布新剧照 "小贱贱"韦德被改造前造型曝光

    时光网讯福斯出品的科幻片《死侍》今天发布新剧照,其中一张是较为罕见的死侍在被改造之前的剧照,其余两张剧照都是死侍在执行任务中的状态。据外媒推测,片方此时发布剧照,预计是为了给不久之后影片发布首款正式预...

    2021年超详细的java学习路线总结—纯干货分享

    本文整理了java开发的学习路线和相关的学习资源,非常适合零基础入门java的同学,希望大家在学习的时候,能够节省时间。纯干货,良心推荐!第一阶段:Java基础重点知识点:数据类型、核心语法、面向对象...

    不用海淘,真黑五来到你身边:亚马逊15件热卖爆款推荐!

    Fujifilm富士instaxMini8小黄人拍立得相机(黄色/蓝色)扫二维码进入购物页面黑五是入手一个轻巧可爱的拍立得相机的好时机,此款是mini8的小黄人特别版,除了颜色涂装成小黄人...

    2025 年 Python 爬虫四大前沿技术:从异步到 AI

    作为互联网大厂的后端Python爬虫开发,你是否也曾遇到过这些痛点:面对海量目标URL,单线程爬虫爬取一周还没完成任务;动态渲染的SPA页面,requests库返回的全是空白代码;好不容易...

    最贱超级英雄《死侍》来了!_死侍超燃

    死侍Deadpool(2016)导演:蒂姆·米勒编剧:略特·里斯/保罗·沃尼克主演:瑞恩·雷诺兹/莫蕾娜·巴卡林/吉娜·卡拉诺/艾德·斯克林/T·J·米勒类型:动作/...

    停止javascript的ajax请求,取消axios请求,取消reactfetch请求

    一、Ajax原生里可以通过XMLHttpRequest对象上的abort方法来中断ajax。注意abort方法不能阻止向服务器发送请求,只能停止当前ajax请求。停止javascript的ajax请求...