js 原型和原型链

js 原型和原型链

1. 原型是什么

ES6 之前,JS 没有类和继承的概念,JS 是通过原型来实现继承的。在 JS 中一个构造函数默认带有一个prototype 属性,这个的属性值是一个对象,同时这个prototype 对象自带有一个 constructor 属性,这个属性指向这个构造函数,同时每一个实例都会有一个 _proto_ 属性指向这个 prototype 对象,我们可以把这个叫做隐式原型,我们在使用一个实例的方法的时候,会先检查这个实例中是否有这个方法,没有的话就会检查这个 prototype 对象是否有这个方法

2. 原型链是什么

基于这个规则,如果让原型对象指向另一个类型的实例,即 constructor1.protoytpe = instance2,这时候如果试图引用 constructor1 构造的实例 instance1 的某个属性 p1,首先会在 instance1 内部属性中找一遍,接着会在 instance1._proto_(constructor1.prototype) 即是 instance2 中寻找 p1搜寻轨迹:instance1->instance2->constructor2.prototype……->Object.prototype

这即是原型链,原型链顶端是 Object.prototype

补充学习:

每个函数都有一个 prototype 属性,这个属性指向了一个对象,这个对象正是调用该函数而创建的实例的原型。那么什么是原型呢,可以这样理解,每一个 JavaScript 对象在创建的时候就会预制管理另一个对象,这个对象就是我们所说的原型每一个对象都会从原型继承属性,如图:

图片说明

那么怎么表示实例与实例原型的关系呢,这时候就要用到第二个属性 _proto_ 这是每一个JS 对象都会有的一个属性,指向这个对象的原型,如图:

person.__proto__  ——>  Person.prototype

图片说明

既然实例对象和构造函数都可以指向原型,那么原型是否有属性指向构造函数或者实例呢?原型没有属性可以指向实例,因为一个构造函数可以生成多个实例,但是原型有属性可以直接指向构造函数,通过 constructor 即可。

接下来讲解实例和原型的关系:

当读取实例的属性时,如果找不到,就会查找与对象相关的原型中的属性,如果还查不到,就去找原型的原型,一直找到最顶层,那么原型的原型是什么呢?首先,原型也是一个对象,既然是对象,我们就可以通过构造函数的方式创建它,所以原型对象就是通过Object 构造函数生成的,如图:

图片说明

那么 Object.prototype 的原型呢,我们可以打印console.log(Object.prototype.__proto__ ===null),返回true。

null 表示没有对象,即该处不应有值,所以Object.prototype 没有原型,如图:

图片说明

图中这条蓝色的线即是原型链

最后补充三点:

constructor:
function Person(){
}
var person = new Person();
console.log(Person === person.constructor);

原本 person 中没有 constructor 属性,当不能读取到 constructor 属性时,会从 person 的原型中读取,所以指向构造函数Person

__proto__

绝大部分浏览器支持这个非标准的方法访问原型,然而它并不存在于 Person.prototype 中,实际上它来自Object.prototype,当使用obj.__proto__时,可以理解为返回来Object.getPrototype(obj)

JavaScript 文章被收录于专栏

前端技术分享

全部评论

相关推荐

霁华Tel:秋招结束了,好累。我自编了一篇对话,语言别人看不懂,我觉得有某种力量在控制我的身体,我明明觉得有些东西就在眼前,但身边的人却说啥也没有,有神秘人通过电视,手机等在暗暗的给我发信号,我有时候会突然觉得身体的某一部分不属于我了。面对不同的人或场合,我表现出不一样的自己,以至于都不知道自己到底是什么样子的人。我觉得我已经做的很好,不需要其他人的建议和批评,我有些时候难以控制的兴奋,但是呼吸都让人开心。
点赞 评论 收藏
分享
11-27 12:36
已编辑
门头沟学院 前端工程师
Apries:这个阶段来说,很厉害很厉害了,不过写的简历确实不是很行,优势删掉吧,其他的还行
点赞 评论 收藏
分享
评论
2
收藏
分享
牛客网
牛客企业服务