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对select标签的控制(option选项/select)
Jan 31 Javascript
原生js实现淘宝首页点击按钮缓慢回到顶部效果
Apr 06 Javascript
jQuery使用zTree插件实现树形菜单和异步加载
Feb 25 Javascript
JavaScript中双向数据绑定详解
May 03 Javascript
不得不看之JavaScript构造函数及new运算符
Aug 21 Javascript
js实现图片放大展示效果
Aug 30 Javascript
解决vue build打包之后首页白屏的问题
Mar 06 Javascript
vue this.reload 方法 配置
Sep 12 Javascript
Electron 如何调用本地模块的方法
Feb 01 Javascript
JavaScript Image对象实现原理实例解析
Aug 26 Javascript
微信小程序实现拼图小游戏
Oct 22 Javascript
js基于canvas实现时钟组件
Feb 07 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下MYSQL limit的优化
2008/01/10 PHP
php下HTTP Response中的Chunked编码实现方法
2008/11/19 PHP
PHP下操作Linux消息队列完成进程间通信的方法
2010/07/24 PHP
Php图像处理类代码分享
2012/01/19 PHP
CI框架中zip类应用示例
2014/06/17 PHP
php实现按照权重随机排序数据的方法
2015/01/09 PHP
JavaScript 计算图片加载数量的代码
2011/01/01 Javascript
JavaScript prototype属性深入介绍
2012/11/27 Javascript
javascript页面加载完执行事件代码
2014/02/11 Javascript
Jquery 监视按键,按下回车键触发某方法的实现代码
2014/05/11 Javascript
document.write的几点使用心得
2014/05/14 Javascript
JavaScript获取DOM元素的11种方法总结
2015/04/25 Javascript
JavaScript实现仿网易通行证表单验证
2015/05/25 Javascript
学习JavaScript设计模式(接口)
2015/11/26 Javascript
jquery+php实现滚动的数字特效
2015/11/29 Javascript
jQuery获取单击节点对象的方法
2016/06/02 Javascript
有趣的bootstrap走动进度条
2016/12/01 Javascript
解决同一页面中两个iframe互相调用jquery,js函数的方法
2016/12/12 Javascript
利用JQUERY实现多个AJAX请求等待的实例
2017/12/14 jQuery
js和jQuery以及easyui实现对下拉框的指定赋值方法
2018/01/23 jQuery
Nodejs中的require函数的具体使用方法
2019/04/02 NodeJs
在Vue中使用antv的示例代码
2020/06/29 Javascript
python3读取MySQL-Front的MYSQL密码
2017/05/03 Python
Python中动态检测编码chardet的使用教程
2017/07/06 Python
Django中自定义模型管理器(Manager)及方法
2019/09/23 Python
python matplotlib如何给图中的点加标签
2019/11/14 Python
python多进程并发demo实例解析
2019/12/13 Python
python的slice notation的特殊用法详解
2019/12/27 Python
Python3查找列表中重复元素的个数的3种方法详解
2020/02/13 Python
澳大利亚领先的宠物用品商店:VetSupply
2017/09/08 全球购物
关于Assembly命名空间的三个面试题
2015/07/23 面试题
反腐倡廉警示教育活动总结
2014/05/05 职场文书
2014银行领导班子四风对照检查材料思想汇报
2014/09/25 职场文书
党校个人总结
2015/03/04 职场文书
班主任自我评价范文
2015/03/11 职场文书
macos系统如何实现微信双开? mac登录两个微信以上微信的技巧
2022/07/23 数码科技