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 相关文章推荐
HTML页面如何象ASP一样接受参数
Feb 07 Javascript
javascript基于jQuery的表格悬停变色/恢复,表格点击变色/恢复,点击行选Checkbox
Aug 05 Javascript
JavaScript 继承详解(三)
Jul 13 Javascript
javascript 学习笔记(八)javascript对象
Apr 12 Javascript
JavaScript 基础篇(一)
Mar 30 Javascript
快速学习jQuery插件 Cookie插件使用方法
Dec 01 Javascript
Vue.js创建Calendar日历效果
Nov 03 Javascript
Sequelize中用group by进行分组聚合查询
Dec 12 Javascript
Angular.js通过自定义指令directive实现滑块滑动效果
Oct 13 Javascript
一个因@click.stop引发的bug的解决
Jan 08 Javascript
Javascript Worker子线程代码实例
Feb 20 Javascript
带你彻底理解JavaScript中的原型对象
Apr 14 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网站基础优化方法小结
2008/09/29 PHP
php截取html字符串及自动补全html标签的方法
2015/01/15 PHP
PHP chop()函数讲解
2019/02/11 PHP
utf-8编码引起js输出中文乱码的解决办法
2010/06/23 Javascript
JQUERY dialog的用法详细解析
2013/12/19 Javascript
基于javascript实现listbox左右移动
2016/01/29 Javascript
基于javascript实现表格的简单操作
2016/05/21 Javascript
jQuery Select下拉框操作小结(推荐)
2016/07/22 Javascript
炫酷的js手风琴效果
2016/10/13 Javascript
详解Jquery 遍历数组之$().each方法与$.each()方法介绍
2017/01/09 Javascript
prototype与__proto__区别详细介绍
2017/01/09 Javascript
JS和canvas实现俄罗斯方块
2017/03/14 Javascript
基于vue-element组件实现音乐播放器功能
2018/05/06 Javascript
详解JavaScript添加给定的标签选项
2018/09/17 Javascript
javascript关于“时间”的一次探索
2019/07/24 Javascript
vue中实现点击按钮滚动到页面对应位置的方法(使用c3平滑属性实现)
2019/12/29 Javascript
小程序如何定位所在城市及发起周边搜索
2020/02/11 Javascript
在vue中通过render函数给子组件设置ref操作
2020/11/17 Vue.js
python抓取网页中图片并保存到本地
2015/12/01 Python
详解用python实现简单的遗传算法
2018/01/02 Python
Python基于WordCloud制作词云图
2019/11/29 Python
基于Python爬取京东双十一商品价格曲线
2020/10/23 Python
澳大利亚的奢侈品牌:Oroton
2016/08/26 全球购物
加拿大领先的冒险和户外零售商:Atmosphere
2017/12/19 全球购物
墨西哥网上超市:Superama
2018/07/10 全球购物
波兰购物网站:MALL.PL
2019/05/01 全球购物
Puccini乌克兰:购买行李箱、女士手袋网上商店
2020/08/06 全球购物
《梅兰芳学艺》教学反思
2014/02/24 职场文书
我的小天地教学反思
2014/04/30 职场文书
迎新晚会策划方案
2014/06/13 职场文书
员工三分钟演讲稿
2014/08/19 职场文书
德育标兵事迹材料
2014/08/24 职场文书
员工给公司的建议书
2019/06/24 职场文书
Python可变集合和不可变集合的构造方法大全
2021/12/06 Python
详细聊聊Oracle表碎片对性能有多大的影响
2022/03/19 Oracle
Python matplotlib绘制条形统计图 处理多个实验多组观测值
2022/04/21 Python