JS原型、原型链深入理解


Posted in Javascript onFebruary 27, 2016

原型是JavaScript中一个比较难理解的概念,原型相关的属性也比较多,对象有”prototype”属性,函数对象有”prototype”属性,原型对象有”constructor”属性。

一、初识原型
在JavaScript中,原型也是一个对象,通过原型可以实现对象的属性继承,JavaScript的对象中都包含了一个”[[Prototype]]”内部属性,这个属性所对应的就是该对象的原型。
“[[Prototype]]”作为对象的内部属性,是不能被直接访问的。所以为了方便查看一个对象的原型,Firefox和Chrome中提供了__proto__这个非标准(不是所有浏览器都支持)的访问器(ECMA引入了标准对象原型访问器”Object.getPrototype(object)”)。在JavaScript的原型对象中,还包含一个”constructor”属性,这个属性对应创建所有指向该原型的实例的构造函数

二、规则
在JavaScript中,每个函数 都有一个prototype属性,当一个函数被用作构造函数来创建实例时,这个函数的prototype属性值会被作为原型赋值给所有对象实例(也就是设置 实例的`__proto__`属性),也就是说,所有实例的原型引用的是函数的prototype属性。(****`只有函数对象才会有这个属性!`****)

new 的过程分为三步 

var p = new Person('张三',20);

1. var p={}; 初始化一个对象p。
2. p._proto_=Person.prototype;,将对象p的 __proto__ 属性设置为 Person.prototype
3. Person.call(p,”张三”,20);调用构造函数Person来初始化p。关于call/apply使用

三、初识Object
Object对象本身是一个函数对象。(CODE TEST) 既然是Object函数,就肯定会有prototype属性,所以可以看到”Object.prototype”的值就是”Object {}”这个原型对象。反过来,当访问”Object.prototype”对象的”constructor”这个属性的时候,就得到了Obejct函数。
另外,当通过”Object.prototype._proto_”获取Object原型的原型的时候,将会得到”null”,也就是说”Object {}”原型对象就是原型链的终点了。
四、初识Function
如上面例子中的构造函数,JavaScript中函数也是对象,所以就可以通过_proto_查找到构造函数对象的原型。
Function对象作为一个函数,就会有prototype属性,该属性将对应”function () {}”对象。
Function对象作为一个对象,就有__proto__属性,该属性对应”Function.prototype”,也就是说,”Function._proto_ === Function.prototype”。

在这里对“prototype”和“proto”进行简单的介绍:
对于所有的对象,都有__proto__属性,这个属性对应该对象的原型.
对于函数对象,除了__proto__属性之外,还有prototype属性,当一个函数被用作构造函数来创建实例时,该函数的prototype属性值将被作为原型赋值给所有对象实例(也就是设置实例的__proto__属性)

JS原型、原型链深入理解

原型链结构图

原型链
因为每个对象和原型都有原型,对象的原型指向原型对象,
而父的原型又指向父的父,这种原型层层连接起来的就构成了原型链。

一、属性查找
当查找一个对象的属性时,JavaScript 会向上遍历原型链,直到找到给定名称的属性为止,到查找到达原型链的顶部(也就是 Object.prototype),如果仍然没有找到指定的属性,就会返回 undefined。

function Person(name, age){ 
    this.name = name; 
    this.age = age; 
  } 
Person.prototype.MaxNumber = 9999;
Person.__proto__.MinNumber = -9999;
var will = new Person("Will", 28); 
console.log(will.MaxNumber); // 9999 
console.log(will.MinNumber); // undefined

在这个例子中分别给”Person.prototype “和” Person.proto”这两个原型对象添加了”MaxNumber “和”MinNumber”属性,这里就需要弄清”prototype”和”proto”的区别了。

“Person.prototype “对应的就是Person构造出来所有实例的原型,也就是说”Person.prototype “属于这些实例原型链的一部分,所以当这些实例进行属性查找时候,就会引用到”Person.prototype “中的属性。

对象创建方式影响原型链

var July = { 
    name: "张三", 
    age: 28, 
    getInfo: function(){ 
      console.log(this.name + " is " + this.age + " years old"); 
    }
  } 
 console.log(July.getInfo());

当使用这种方式创建一个对象的时候,原型链就变成下图了. July对象的原型是”Object.prototype”也就是说对象的构建方式会影响原型链的形式。

JS原型、原型链深入理解

{}对象原型链结构图

综图所述
1. 所有的对象都有__proto__属性,该属性对应该对象的原型.
2. 所有的函数对象都有prototype属性,该属性的值会被赋值给该函数创建的对3. 象的_proto_属性.
4. 所有的原型对象都有constructor属性,该属性对应创建所有指向该原型的实例的构造函数.
5. 函数对象和原型对象通过prototype和constructor属性进行相互关联.

以上就会关于JS原型、原型链的详细内容介绍,希望对大家的学习有所帮助。

Javascript 相关文章推荐
JavaScript 实现类的多种方法实例
May 01 Javascript
通过Javascript读取本地Excel文件内容的代码示例
Apr 08 Javascript
基于JavaScript实现生成名片、链接等二维码
Sep 20 Javascript
jquery实现的动态回到顶部特效代码
Oct 28 Javascript
js+ajax实现获取文件大小的方法
Dec 08 Javascript
Vue.js一个文件对应一个组件实践
Oct 27 Javascript
JavaScript数组去重的6个方法
Jan 21 Javascript
zTree树形插件异步加载方法详解
Jun 14 Javascript
bootstrap table表格客户端分页实例
Aug 07 Javascript
BootStrap给table表格的每一行添加一个按钮事件
Sep 07 Javascript
vue实现word,pdf文件的导出功能
Jul 31 Javascript
Typescript类型系统FLOW静态检查基本规范
May 25 Javascript
Javascript中Date类型和Math类型详解
Feb 27 #Javascript
原生javascript实现匀速运动动画效果
Feb 26 #Javascript
探索angularjs+requirejs全面实现按需加载的套路
Feb 26 #Javascript
JavaScript代码生成PDF文件的方法
Feb 26 #Javascript
JavaScript 定时器 SetTimeout之定时刷新窗口和关闭窗口(代码超简单)
Feb 26 #Javascript
自动完成的搜索框javascript实现
Feb 26 #Javascript
jQuery实现控制文字内容溢出用省略号(…)表示的方法
Feb 26 #Javascript
You might like
[原创]ThinkPHP中SHOW_RUN_TIME不能正常显示运行时间的解决方法
2015/10/10 PHP
thinkphp如何获取客户端IP
2015/11/03 PHP
php中数组最简单的使用方法
2020/12/27 PHP
web网页按比例显示图片实现原理及js代码
2013/08/09 Javascript
javascript常用代码段搜集
2014/12/04 Javascript
javascript iframe跨域详解
2016/10/26 Javascript
js以分隔符分隔数组中的元素并转换为字符串的方法
2016/11/16 Javascript
JS新包管理工具yarn和npm的对比与使用入门
2016/12/09 Javascript
微信小程序实现滑动删除效果
2017/05/19 Javascript
JS+canvas实现的五子棋游戏【人机大战版】
2017/07/19 Javascript
JS数组交集、并集、差集的示例代码
2017/08/23 Javascript
webpack学习笔记之优化缓存、合并、懒加载
2017/08/24 Javascript
Javascript实现运算符重载详解
2018/04/07 Javascript
JS模拟实现哈希表及应用详解
2018/05/04 Javascript
在vue中v-bind使用三目运算符绑定class的实例
2018/09/29 Javascript
JavaScript实现动态留言板
2020/03/16 Javascript
JavaScript代码压缩工具UglifyJS和Google Closure Compiler的基本用法
2020/04/13 Javascript
微信小程序学习总结(一)项目创建与目录结构分析
2020/06/04 Javascript
JS如何定义用字符串拼接的变量
2020/07/11 Javascript
ant design vue中日期选择框混合时间选择器的用法说明
2020/10/27 Javascript
[01:04:32]DOTA2-DPC中国联赛 正赛 Aster vs LBZS BO3 第二场 2月23日
2021/03/11 DOTA
python使用tcp实现局域网内文件传输
2020/03/20 Python
python中下标和切片的使用方法解析
2019/08/27 Python
python画环形图的方法
2020/03/25 Python
Jupyter notebook运行Spark+Scala教程
2020/04/10 Python
Python使用socketServer包搭建简易服务器过程详解
2020/06/12 Python
基于Python和C++实现删除链表的节点
2020/07/06 Python
详解淘宝H5 sign加密算法
2020/08/25 HTML / CSS
微软美国官方网站:Microsoft美国
2018/05/10 全球购物
培训主管的岗位职责
2013/11/23 职场文书
个人求职简历中英文自我评价
2013/12/16 职场文书
销售人员获奖感言
2014/02/05 职场文书
个人课题方案
2014/05/08 职场文书
四风自我剖析材料
2014/09/30 职场文书
教师党员个人自我评价
2015/03/04 职场文书
聘任书格式及范文
2015/09/21 职场文书