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 相关文章推荐
jQuery选择头像并实时显示的代码
Jun 27 Javascript
jquery中动态效果小结
Dec 16 Javascript
js open() 与showModalDialog()方法使用介绍
Sep 10 Javascript
使用JS CSS去除IE链接虚线框的三种方法
Nov 14 Javascript
javascript日期计算实例分析
Jun 29 Javascript
Vue.js 表单校验插件
Aug 14 Javascript
LayUI表格批量删除方法
Aug 15 Javascript
Vue项目pdf(base64)转图片遇到的问题及解决方法
Oct 19 Javascript
vue实现多级菜单效果
Oct 19 Javascript
vue element 中的table动态渲染实现(动态表头)
Nov 21 Javascript
详解微信小程序中var、let、const用法与区别
Jan 11 Javascript
原生JavaScript实现弹幕组件的示例代码
Oct 12 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
phplock(php进程锁) v1.0 beta1
2009/11/24 PHP
Linux下实现PHP多进程的方法分享
2012/08/16 PHP
PHP连接sql server 2005环境配置及问题解决
2014/08/08 PHP
详谈PHP编码转换问题
2015/07/28 PHP
学习php设计模式 php实现命令模式(command)
2015/12/08 PHP
PHP基于DateTime类解决Unix时间戳与日期互转问题【针对1970年前及2038年后时间戳】
2018/06/13 PHP
详解PHP变量传值赋值和引用赋值变量销毁
2019/03/23 PHP
刷新时清空文本框内容的js代码
2007/04/23 Javascript
js 判断 enter 事件
2009/02/12 Javascript
Jquery 滑入滑出效果实现代码
2010/03/27 Javascript
在图片上显示左右箭头类似翻页的代码
2013/03/04 Javascript
JS去除数组重复值的五种不同方法
2013/09/06 Javascript
jquery 按键盘上的enter事件
2014/05/11 Javascript
node.js中的fs.fsync方法使用说明
2014/12/15 Javascript
BootstrapTable refresh 方法使用实例简单介绍
2017/02/20 Javascript
基于bootstrap实现多个下拉框同时搜索功能
2017/07/19 Javascript
vue中计算属性(computed)、methods和watched之间的区别
2017/07/27 Javascript
JavaScript中使用参数个数实现重载功能
2017/09/01 Javascript
vue实现a标签点击高亮方法
2018/03/17 Javascript
少女风vue组件库的制作全过程
2019/05/15 Javascript
Vue form表单动态添加组件实战案例
2019/09/02 Javascript
Python中使用strip()方法删除字符串中空格的教程
2015/05/20 Python
Python使用Scrapy爬虫框架全站爬取图片并保存本地的实现代码
2018/03/04 Python
python实现列表的排序方法分享
2019/07/01 Python
Python 使用指定的网卡发送HTTP请求的实例
2019/08/21 Python
Django实现将views.py中的数据传递到前端html页面,并展示
2020/03/16 Python
PyCharm2020最新激活码+激活码补丁(亲测最新版PyCharm2020.2激活成功)
2020/11/25 Python
html5小技巧之通过document.head获取head元素
2014/06/04 HTML / CSS
女士和男士时尚鞋在线购物:Shoespie
2019/02/28 全球购物
护士自荐信范文
2013/12/15 职场文书
计算机专业毕业生自荐信
2013/12/31 职场文书
文秘大学生求职信
2014/02/25 职场文书
法人代表授权委托书范文
2014/09/10 职场文书
2014年助理工程师工作总结
2014/11/14 职场文书
图书借阅制度范本
2015/08/06 职场文书
高一语文教学反思
2016/02/16 职场文书