原型与原型链

在JavaScript中,原型(prototype)和原型链(prototype chain)是理解对象如何继承属性和方法的关键概念。

原型

每一个对象(函数也是对象)都有一个特殊的属性叫做原型(prototype) ,它指向另一个对象,这个对象(构造函数.prototype)被称为原型对象, 原型对象是用来共享属性和方法的。

javascript 复制代码
//构造函数:Person
function Person(name, age){
    this.name = name
    this.age = age
}
//实例对象:obj
var obj = new Person('Jack', 26)
//原型对象:Person.prototype
Person.prototype.constructor === Person

原型对象:

(1),原型对象有一个constructor属性指向构造函数本身(Person)。

(2),原型对象是一个普通的对象,它包含属性和方法。

(3),原型对象的属性和方法会被继承到所有通过原型链与它相连的对象。

javascript 复制代码
//构造函数:Person
function Person(name, age){
    this.name = name
    this.age = age
}
//实例对象:obj
var obj = new Person('Jack', 26)
//原型对象:Person.prototype
Person.prototype.constructor === Person
//原型对象也有属性和方法
Person.prototype.say = function() {
    console.log('hi, world!')
}
//原型对象的方法可被继承
obj.say()  //hi, world!

隐式原型(proto

在js中,每个对象都有一个" proto "属性**(左右两边两个短下划线)**,这个__proto__就被称为隐式原型。

javascript 复制代码
obj.__proto__ === Person.prototype //true

(1)每个js对象都有一个隐藏的原型对象属性__proto__,它指向创建它的构造函数的原型对象(Person.prototype)

(2)proto__存在的意义在于为原型链查找提供方向,原型链查找靠的是__proto,而不是prototype

原型链

按照上面所说,原型对象也应该有隐式原型。确实是的。

(1) Person.prototype的隐式原型(proto)就是Object.prototype

(2) 所有的对象,包括构造函数的原型对象,最终都继承自 Object.prototype ,这是js原型链的顶点

(3)Object.prototype作为原型链的顶端,位于原型链的最末端因此,它不再有自己的原型,所以Object.prototype.proto 指向null,表示原型链的终点

每个对象都有一个原型(prototype),它指向另外一个对象,而指向的对象又存在属性(proto)指向另外一个对象。当我们访问对象(obj)的属性时,会先在对象定义的属性中进行查找,没找到就会沿着__proto__一路向上查找,最终形成一个链式结构,这整个链式结构就叫做原型链。

如果在原型链中找到了这个属性,就返回找到的属性值;如果整个原型链都没找到这个属性值,则返回 undefined,没找到方法直接报错(not a function)。

思考

javascript 复制代码
//构造函数:Person
function Person(name, age){
    this.name = name
    this.age = age
}
//原型对象也有属性和方法
Person.prototype.say = function() {
    console.log('hi, world!')
}
//原型对象也有属性和方法
Object.prototype.say = function() {
    console.log('oh, my god!')
}
//实例对象:obj
var obj = new Person('Jack', 26)


Person.say() // ????

你觉得会输出什么。-------答案是'oh, my god!'

首先,补充个知识点。

构造函数Person的隐式原型( proto)指向 Function.prototype, 函数对象的__proto__指向Function.prototype,即

javascript 复制代码
Person.__proto__ === Function.prototype
Function.prototype === Function.__proto__

而且

javascript 复制代码
Function.prototype.__proto__ === Object.prototype

如果在深究一点,Object也是函数对象,Object.proto 也会指向Function.prototype

构造函数Person也有constructor属性,这个属性指向创建该函数的构造函数;如果自己没有定义构造函数,会指向到 Function

javascript 复制代码
Person.constructor === Function

辣么,完整的原型链诞生了!

现在看图,顺便想起前文标红的句子" 原型链查找靠的是__proto__,而不是prototype",上述的思考题明白为什么打印'oh, my god!'了吧:

原型链从实例对象开始查找,不是从构造函数开始查找,构造函数不具备相同的原型链机制。

Person在自身没有找到say,如果要到原型对象上查找,正确的方式应该是 obj.prototype.say。

(好像很绕~)

但是,记住一点:

不要用构造函数去访问方法,尽量只使用实例去访问方法!!!

---------------------------------------------------------------------------------------------------------------------------------

内容参考@Yi_qian1000,请移步细阅

相关推荐
刘发财37 分钟前
前端2秒生成500页矢量PDF,rust真的强到没朋友
前端·javascript·rust
郑州光合科技余经理1 小时前
国际版外卖系统:税率字段怎么和订单主流程解耦
android·java·开发语言·前端·后端·php·ai编程
梦想平凡2 小时前
百游棋牌源代码开发搭建教程(十):隔离部署、备份恢复与双端验收
java·前端·javascript·数据库·源代码管理
yume_sibai3 小时前
06-Rust Web 开发实战(Axum 框架 + 数据库 + JWT 认证 + 中间件 + 部署)
前端·数据库·rust
计算机魔术师4 小时前
特朗普上台打给黄仁勋:AI末日论是骗局,我们绝不让它发生
前端
troy1284 小时前
Python 基础语法(八):Web 后端开发、数据分析与可视化、网络爬虫、人工智能 / 大模型应用
前端·python·数据分析
计算机魔术师4 小时前
CEO说要慢下来,黑客说别做梦了——同一篇论文,两种命运
前端
kyriewen5 小时前
我花3天抓了一个幽灵bug,凶手藏在第4层
前端·javascript·程序员
IT_陈寒6 小时前
Java里用Stream.parallel()翻车实录,这性能还不如单线程
前端·人工智能·后端
wangchunyu1146 小时前
JavaScript 零基础入门教程
前端