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 相关文章推荐
网站被黑的假象--ARP欺骗之页面中加入一段js
May 16 Javascript
javascript 客户端验证上传图片的大小(兼容IE和火狐)
Aug 15 Javascript
jQuery隔行变色与普通JS写法的对比
Apr 21 Javascript
jquery $.each 和for怎么跳出循环终止本次循环
Sep 27 Javascript
jQuery Validate表单验证深入学习
Dec 18 Javascript
Bootstrap实现下拉菜单效果
Apr 29 Javascript
全屏滚动插件fullPage.js使用实例解析
Oct 21 Javascript
微信小程序 详解下拉加载与上拉刷新实现方法
Jan 13 Javascript
微信小程序图片横向左右滑动案例
May 19 Javascript
vue2.0 和 animate.css的结合使用
Dec 12 Javascript
ionic+html5+API实现双击返回键退出应用
Sep 17 Javascript
Echarts如何重新渲染实例详解
May 30 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
PHP JSON 数据解析代码
2010/05/26 PHP
php合并js请求的例子
2013/11/01 PHP
php实现的百度搜索某地天气的小偷代码
2014/04/23 PHP
php实现的简单美国商品税计算函数
2015/07/13 PHP
PHP上传Excel文件导入数据到MySQL数据库示例
2016/10/25 PHP
PHP使用curl函数发送Post请求的注意事项
2016/11/26 PHP
利用jQuery设计一个简单的web音乐播放器的实例分享
2016/03/08 Javascript
总结JavaScript的正则与其他语言的不同之处
2016/08/25 Javascript
微信页面倒计时代码(解决safari不兼容date的问题)
2016/12/13 Javascript
canvas滤镜效果实现代码
2017/02/06 Javascript
简单实现js鼠标跟随效果
2020/08/02 Javascript
微信小程序radio组件使用详解
2018/01/31 Javascript
基于vue-video-player自定义播放器的方法
2018/03/21 Javascript
vue中input的v-model清空操作
2019/09/06 Javascript
layui实现二维码弹窗、并下载到本地的方法
2019/09/25 Javascript
node.js使用mongoose操作数据库实现购物车的增、删、改、查功能示例
2019/12/23 Javascript
vue3.0搭配.net core实现文件上传组件
2020/10/29 Javascript
[02:40]DOTA2超级联赛专访430 从小就爱玩对抗性游戏
2013/06/18 DOTA
[42:24]完美世界DOTA2联赛循环赛 LBZS vs DM BO2第一场 11.01
2020/11/02 DOTA
[52:03]DOTA2-DPC中国联赛 正赛 Ehome vs iG BO3 第三场 1月31日
2021/03/11 DOTA
Anaconda2 5.2.0安装使用图文教程
2018/09/19 Python
python 标准差计算的实现(std)
2019/07/29 Python
python如何把字符串类型list转换成list
2020/02/18 Python
关于HTML5你必须知道的28个新特性,新技巧以及新技术
2012/05/28 HTML / CSS
HTML5 创建canvas元素示例代码
2014/06/04 HTML / CSS
大专自我鉴定范文
2013/10/23 职场文书
应届生的求职推荐信范文
2013/11/30 职场文书
迎八一活动主题
2014/01/31 职场文书
秸秆管理实施方案
2014/03/15 职场文书
云南省召开党的群众路线教育实践活动总结会议新闻稿
2014/10/21 职场文书
党员“一帮一”活动总结
2015/05/07 职场文书
2016年优秀共产党员先进事迹材料
2016/02/29 职场文书
导游词之南京莫愁湖公园
2019/11/13 职场文书
一篇文章学会Vue中间件管道
2021/06/20 Vue.js
Python Django / Flask如何使用Elasticsearch
2022/04/19 Python
Oracle 11g数据库使用expdp每周进行数据备份并上传到备份服务器
2022/06/28 Oracle