文章目录

  • 一、JS原型链简要解释
  • 二、JS原型链详细解释
    • 1.构造函数
    • 2.原型对象
    • 3.`__proto__`
    • 4.原型链
  • 总结

一、JS原型链简要解释

原型是function对象上的一个属性, 它表示构造函数构造出来的对象的共有祖先, 被通过构造函数构造出来的对象上有一个__proto__属性指向该函数的prototype, prototype本身也是一个对象, 所以这种__proto__与prototype之间的连接关系会变成一个链条, 这就是原型链, 通过原型链我们可以提取共有属性, 并实现继承

二、JS原型链详细解释

1.构造函数

我们先复习一下构造函数的知识:

function Person(name, age, job) {this.name = name;this.age = age;this.job = job;this.sayName = function() { alert(this.name) }
}
var person1 = new Person('Zaxlct', 28, 'Software Engineer');
var person2 = new Person('Mick', 23, 'Doctor');

上面的例子中 person1 和 person2 都是 Person 的实例。这两个实例都有一个 constructor (构造函数)属性,该属性(是一个指针)指向 Person。 即:

  console.log(person1.constructor == Person); //trueconsole.log(person2.constructor == Person); //true

我们要记住两个概念(构造函数,实例):
person1 和 person2 都是 构造函数 Person 的实例

一个公式:
实例的构造函数属性(constructor)指向构造函数。

2.原型对象

在 JavaScript 中,每当定义一个对象(函数也是对象)时候,对象中都会包含一些预定义的属性。
其中每个函数对象都有一个prototype 属性,这个属性指向函数的原型对象

function Person() {}
Person.prototype.name = 'Zaxlct';
Person.prototype.sayName = function() {alert(this.name);
}var person1 = new Person();
person1.sayName(); // 'Zaxlct'var person2 = new Person();
person2.sayName(); // 'Zaxlct'console.log(person1.sayName == person2.sayName); //true

Person.prototype 也是Person 的实例;Person.prototype 也有 constructor 属性。

Person.prototype.constructor == Person

也就是在 Person 创建的时候,创建了一个它的实例对象并赋值给它的 prototype,
其主要作用是用于继承

 var Person = function(name){this.name = name; // tip: 当函数执行时这个 this 指的是谁?};Person.prototype.getName = function(){return this.name;  // tip: 当函数执行时这个 this 指的是谁?}var person1 = new person('Mick');person1.getName(); //Mick

从这个例子可以看出,通过给 Person.prototype 设置了一个函数对象的属性,那有 Person 的实例(person1)出来的普通对象就继承了这个属性。


3.__proto__

JS 在创建对象的时候,都有一个叫做__proto__ 的内置属性,用于指向创建它的构造函数的原型对象。
对象 person1 有一个 __proto__属性,创建它的构造函数是 Person,构造函数的原型对象是 Person.prototype ,所以:
person1.proto == Person.prototype

这里需要特别注意的是:
这个连接存在于实例(person1)与构造函数(Person)的原型对象(Person.prototype)之间,而不是存在于实例(person1)与构造函数(Person)之间。

4.原型链

用构造函数、原型、实例之间的关系重温一遍上面的知识。
每个构造函数都有一个原型对象,原型对象有一个属性(constructor)指回构造函数,而实力有一个内部指针(__proto__)指向原型。
那如果当原型是另一个类型的实例的时候呢?那意味着这个原型本身也有一个内部指针指向另一个原型,相应地另一个原型也有一个指针指向另一个构造函数。这样就在实例和原型之间构造了一条原型链。这也是原型链的基本构想。

举个栗子:定义两个类型:SuperType和SubType。这两个类型分别定义了一个属性和一个方法。它们的区别就是 SubType 通过创建 SuperType的实例并将其赋值给自己的原型SubTtype.prototype 实现了对 SuperType的继承。这个赋值重写了 SubType 最初的原型,将其替换为 SuperType 的实例。这意味着 SuperType 实例可以访问的所有属性和方法也会存在于 SubType.prototype。

这里可能会有点乱,我们再举个栗子:

 var animal = function(){};var dog = function(){};animal.price = 2000;dog.prototype = animal;var tidy = new dog();console.log(dog.price) //undefinedconsole.log(tidy.price) // 2000

通过这个栗子可以知道

实例(tidy)和原型对象(dog.prototype)存在一个连接。不过,要明确的真正重要的一点就是,这个连接存在于实例(tidy)与构造函数的原型对象(dog.prototype)之间,而不是存在于实例(tidy)与构造函数(dog)之间。

由此可以基本了解原型链实现继承的原理啦,再看下图:

于是SubType的实例instance,通过其__proto__属性获得到SubType.prototype的属性和方法,又因为SuperType 实例可以访问的所有属性和方法也会存在于 SubType.prototype,所以instance也可以访问到SuperType的属性和方法。

实际上,原型链还有一环。默认情况下,任何函数的默认原型都是一个Object的实例,这意味着这个实例有一个内部指针(__proto__)指向Object.prototype。这也是为什么自定义类型能够继承包括toString()、valueof() 在内的所以默认方法的原因。
完整的原型链如下图:

该图中的instance继承SubType,SubType继承SuperType,而SuperType继承Object。在调用instance.toString()时,实际上调用的是保存在Object.prototype上的方法。


总结

  • 原型和原型链是JS实现继承的一种模型。
  • 原型链的形成是真正是靠__proto__ 而非prototype

借鉴学习于:

  1. 最详尽的 JS 原型与原型链终极详解,没有「可能是」作者:Yi罐可乐
  2. 《JavaScript 高级程序设计》中文译本 第4版

JS原型与原型链详细解释相关推荐

  1. js事件冒泡和传播详细解释

    举栗子 事件输出hello world 事件有两种,一种为事件传播,一种是事件冒泡 事件传播和事件冒泡 这还要从遥远的荒诞说起,两家网景和ie,为了能争夺市场,互相使用相反的技术,当网景使用事件传播的 ...

  2. js中的reduce函数详细解释

    目录 一.数组求和 二.数组去重 三.合并二维数组 四.统计出现的次数 五.按类型进行分类 reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值.循环遍历 ...

  3. 最详细的讲解 JS 原型与原型链

    文章目录 一. 普通对象与函数对象 二. 构造函数 三. 原型对象 四. proto 五. 构造器 六. 原型链 七. Prototype 总结 一. 普通对象与函数对象 JavaScript 中,万 ...

  4. 最详尽的 JS 原型与原型链终极详解(1)(2)(3)===转载

    转载===方便以后复习 原文网址:https://www.jianshu.com/p/dee9f8b14771 一. 普通对象与函数对象 JavaScript 中,万物皆对象!但对象也是有区别的.分为 ...

  5. JavaScript什么是原型和原型链JS

    从事前端这么久,发现原型和原型链一直都是云里雾里,网上看了好多文章.博客也还是不怎么明朗,相信被它困扰的小伙伴,不在少数 以下是我总结的原型和原型链,个人认为是比较浅显易懂的: 原型:构造函数中的 p ...

  6. JS原型与原型链终极详解

     一. 普通对象与函数对象   JavaScript 中,万物皆对象!但对象也是有区别的.分为普通对象和函数对象,Object ,Function 是JS自带的函数对象.下面举例说明 functi ...

  7. js三座大山——原型及原型链

    前言 js的三座大山(原型及原型链.作用域及闭包,异步执行机制及单线程),一直是前端学习和面试中常常遇到的话题,所以深入学习这一块的知识还是很有必要的,下面详细讲解一下我对这一块的理解,记录一下学习过 ...

  8. JS原型、原型链到底是什么?

    前言 在js的学习中,原型毫无疑问是一个难点,但也是一个不可忽视的重点.在前端面试中也是一个高频考题,在接下来的深入学习中,你会发现原型.原型链等知识点其实并不难. 1. "一切皆为对象&q ...

  9. JS经典面试题:JS原型、原型链

    JS是一种基于原型的语言,每一个对象都有一个原型对象,当你试图寻找某个属性时,它不仅仅在该对象上面搜索,还有搜索该对象的原型,或则是该对象原型的原型,一次向上进行搜索,直到找到一个名字匹配的属性或者到 ...

最新文章

  1. Vue 过渡组件,可实现组件或者页面的动画过渡或者css过渡
  2. mysql自然连接和等值连接_mysql sql99语法 内连接等值连接
  3. 计算机CAI应用实例,运用CAI课件辅助实验的实例分析
  4. P4309 [TJOI2013]最长上升子序列 平衡树 + dp
  5. QQ号双主号要求验证码解决方法
  6. python小程序源代码_【程序源代码】微信商城小程序
  7. 将java项目打包为jar
  8. 轻快pdf阅读器 电子书阅读软件电脑版
  9. 前端零基础入门: 用css设置文字样式
  10. oa项目经验描述_项目执行简历中的项目经验怎么写
  11. 手把手教你用Python创建SQL数据库~
  12. Unity DOTween插件和iTween插件使用(笔记)
  13. c语言打砖块小游戏,C语言动画(打砖块游戏)
  14. 第一章 【数据分析师---数据可视化1】 matplotlib 静态图,无互动
  15. CSS手机端的主界面
  16. 爬虫项目:scrapy爬取昵图网全站图片
  17. OCR文本识别网络SAR的学习
  18. 如何判断程序的复杂程度:时间和空间复杂度
  19. 大数据技术之_19_Spark学习_07_Spark 性能调优 + 数据倾斜调优 + 运行资源调优 + 程序开发调优 + Shuffle 调优 + GC 调优 + Spark 企业应用案例
  20. 通向天才之路 : 实时环境映射贴图技术(Real-time Evironmnet Mapping)

热门文章

  1. 在linux下给编辑文件在哪里设置密码,如何在Linux中用Vim对文件进行密码
  2. ImageIO 写出图片
  3. html的绝对路径怎么选择,html的相对路径和绝对路径
  4. futureTask用法
  5. python模拟-食行生鲜登陆
  6. 记一道超级简单的 Java 算法面试题,但无人通过
  7. java计算机毕业设计皮皮狗宠物用品商城源码+程序+lw文档+mysql数据库
  8. 还在为软件测试面试担心?教你一分钟拿捏面试官,轻松拿offer
  9. 小米4c无信号恢复服务器,小米4C用户必知,这8个问题及解决方法一定要了解
  10. 一个类打地鼠的canvas小游戏