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 相关文章推荐
js 操作select相关方法函数
Dec 06 Javascript
Ubuntu 11.10 安装Node.js的方法
Nov 30 Javascript
JavaScript 验证码的实例代码(附效果图)
Mar 22 Javascript
js禁止回车提交表单的示例代码
Dec 23 Javascript
js动态创建标签示例代码
Jun 09 Javascript
js获取checkbox值的方法
Jan 28 Javascript
超级给力的JavaScript的React框架入门教程
Jul 02 Javascript
iframe中使用jquery进行查找的方法【案例分析】
Jun 17 Javascript
node.js请求HTTPS报错:UNABLE_TO_VERIFY_LEAF_SIGNATURE\的解决方法
Dec 18 Javascript
vue.js组件之间传递数据的方法
Jul 10 Javascript
浅谈vue引用静态资源需要注意的事项
Sep 28 Javascript
vue中watch和computed的区别与使用方法
Aug 23 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
如何过滤高亮显示非法字符
2006/10/09 PHP
php sprintf()函数让你的sql操作更安全
2008/07/23 PHP
php eval函数一句话木马代码
2015/05/21 PHP
php 替换文章中的图片路径,下载图片到本地服务器的方法
2018/02/06 PHP
php 后端实现JWT认证方法示例
2018/09/04 PHP
JavaScript 在网页上单击鼠标的地方显示层及关闭层
2012/12/30 Javascript
简单的Jquery遮罩层代码实例
2013/11/14 Javascript
js/jquery解析json和数组格式的方法详解
2014/01/09 Javascript
Javascript让DEDECMS告别手写Tag
2014/09/01 Javascript
JS的location.href跳出框架打开新页面的方法
2014/09/04 Javascript
详解AngularJS中的依赖注入机制
2015/06/17 Javascript
jQuery.each使用详解
2015/07/07 Javascript
JS+CSS实现简单的二级下拉导航菜单效果
2015/09/21 Javascript
JQuery解析XML数据的几个简单实例
2016/05/18 Javascript
request请求获取参数的实现方法(post和get两种方式)
2016/09/27 Javascript
详谈js中标准for循环与foreach(for in)的区别
2017/11/02 Javascript
通过一个简单的例子学会vuex与模块化
2017/11/22 Javascript
vue实践---vue不依赖外部资源实现简单多语操作
2020/09/21 Javascript
谈谈如何手动释放Python的内存
2016/12/17 Python
Python使用Tkinter实现机器人走迷宫
2018/01/22 Python
Python程序员面试题 你必须提前准备!(答案及解析)
2018/01/23 Python
python3实现小球转动抽奖小游戏
2020/04/15 Python
解决python gdal投影坐标系转换的问题
2020/01/17 Python
python3 循环读取excel文件并写入json操作
2020/07/14 Python
HTML5之SVG 2D入门13—svg对决canvas及长处和适用场景分析
2013/01/30 HTML / CSS
Speedo澳大利亚官网:全球领先游泳品牌
2018/02/04 全球购物
美国领先的机场停车聚合商:Airport Parking Reservations
2020/02/28 全球购物
高中生自我评语大全
2014/01/19 职场文书
司法局群众路线教育实践活动开展情况总结
2014/10/25 职场文书
小学运动会开幕词
2015/01/28 职场文书
销售会议开幕词
2015/01/28 职场文书
努力学习保证书
2015/02/26 职场文书
村级干部党员公开承诺事项
2015/05/04 职场文书
小学中队委竞选稿
2015/11/20 职场文书
如何书写邀请函?
2019/06/24 职场文书
2019年最新七夕唯美祝福语(60条)
2019/07/22 职场文书