javascript中的原型链深入理解


Posted in Javascript onFebruary 24, 2014

要弄清楚原型链就要先弄清楚 function 类型,在javascript中没有类的概念,都是函数,所以它是一门函数式的编程语言。类有一个很重要的特性,就是它可以根据它的构造函数来创建以它为模板的对象。在javascript中,函数就有2个功能

第一、 作为一般函数调用
第二、 作为它原型对象的构造函数 也就new()

我们来看一个例子

function a(){ 
this.name = 'a'; 
}

当创建一个函数,它会发生什么呢?

第一、它会创建1个函数对象 也就是a 本身

第二、它会创建1个原型对象@a(用@来表示)

第三、函数对象会有一个prototype指针,它指向了对应的原型对象,这里就指向了@a

第四、@a对象中有一个construtor指针,指向它的构造函数,这里就指向了a

http://img.blog.csdn.net/20140222125611500?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGpsMTU3MDEx/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast

这个prototype属性究竟有什么用呢?

其实prototype 属性表示当前函数能够控制的范围(或者说它指明了当前函数是谁的构造函数),这里a就是@a原型对象的构造函数,所以我们会看见有这种写法

function a(){ 
this.name = 'a'; 
} var a1 = new a();

这就和其他常见语言相似了,new 就是调用原型对象(通过prototype指针)里面构造函数(constructor)创建一个新的对象实例。

那么修改了prototype指向对象里面的属性,也就影响了所有以它为模板创建的实例,我们可以这样来验证

function a(){ 
this.name = 'a'; 
} var a1 = new a(); 
a.prototype.age = 1; 
alert(a1.age);

结果:1

那为什么a1对象可以直接访问到age属性呢?a1对象里面我并没有定义age属性啊,

那是因为所有实例里面都会有一个引用_proto_(在firfox,chrome下可以直接访问,ie不支持)指向了这个原型,这里就是指向了@a,

function a(){ 
this.name = 'a'; 
} var a1 = new a(); 
alert(a1._proto_ == a.prototype)

结果:true

在访问属性的时候,会先在a1对象内部中寻找,如果没有,就会顺着_proto_指向的对象里面去寻找,这里会到@a中寻找,找到就返回值,没有找到就返回undefined,用个成语来形容,就是顺藤摸瓜嘛!

至此原型链的含义就出来了,由于原型对象也有一个_proto_指针,又指向了另一个原型,一个接一个,就形成了原型链。Object.prototype是最顶层的原型,所以如果修改了Object.prototype的属性,那么就影响了所有的对象。

在来看一段代码

function a(){ 
this.name = 'a'; 
} function b(){ 
this.age = 1; 
} 
b.prototype = new a(); 
alert(new b().name);

我们显示的将b的原型指向了a的一个实例,然后,b的实例也可以访问a的属性了。这就是javascript的继承了,那为什么b.prototype 指向的是a的一个实例,而不是直接指向a.prototype 呢?
b.prototype = new a.prototype;

如果像上面这么写,修改p.prototype中的属性,那么a的原型也会改变了,相当于是子类修改了父类,并且子类和父类的属性糅合在了一起,这显然是不合适的。换句话说,b也成为了@a的构造函数,a,b成了平级的关系。

我们可以下一个定义:

函数a 继承函数b 也就是让函数a成为函数b原型的一个实例的构造函数,构造函数里面声明的属性是函数a自己的,原型实例里面的属性就是继承b的

var $ = jQuery = function(selector,context){ 
//不可能在自己的构造函数中又一次构造自己,所以返回了另外一个构造函数的实例 
return new init(selector,context); 
} 
jQuery.fn = jQuery.prototype = { 
size:function(){ 
return this.length; 
} 
} function init (selector,context){ 
} 
init.prototype = jQuery.fn;; 
}

这是jquery的一段源码,我们在使用jquery的时候,并没有使用new关键字,那它是如何构造对象的呢?

用上面的知识,可以解释,jquery这里只是一个一般函数的调用,它返回了jquery原型的另外一个构造函数创建的对象,也就是new init()

Javascript 相关文章推荐
基于jQuery的Spin Button自定义文本框数值自增或自减
Jul 17 Javascript
js实现运动logo图片效果及运动元素对象sportBox使用方法
Dec 25 Javascript
JS检测图片大小的实例
Aug 21 Javascript
js控制当再次点击按钮时的间隔时间
Jun 03 Javascript
吐槽一下我所了解的Node.js
Oct 08 Javascript
Node.js如何实现注册邮箱激活功能 (常见)
Jul 23 Javascript
Vue 2.0学习笔记之Vue中的computed属性
Oct 16 Javascript
Vue.js+Layer表格数据绑定与实现更新的实例
Mar 07 Javascript
js实现图片上传到服务器和回显
Jan 19 Javascript
Vue两个版本的区别和使用方法(更深层次了解)
Feb 16 Javascript
javascript使用正则表达式实现注册登入校验
Sep 23 Javascript
解决vue数据不实时更新的问题(数据更改了,但数据不实时更新)
Oct 27 Javascript
JSONP获取Twitter和Facebook文章数的具体步骤
Feb 24 #Javascript
动态加载js、css等文件跨iframe实现
Feb 24 #Javascript
js操纵dom生成下拉列表框的方法
Feb 24 #Javascript
js设置function参数默认值(适合没有传参情况)
Feb 24 #Javascript
JS取request值以及自动执行使用示例
Feb 24 #Javascript
减少访问DOM的次数提升javascript性能
Feb 24 #Javascript
createTextRange()的使用示例含文本框选中部分文字内容
Feb 24 #Javascript
You might like
php下载远程文件类(支持断点续传)
2008/11/14 PHP
PHP获取youku视频真实flv文件地址的方法
2014/12/23 PHP
PHP实现图片不变型裁剪及图片按比例裁剪的方法
2016/01/14 PHP
Yii2框架BootStrap样式的深入理解
2016/11/07 PHP
浅谈PHP中try{}catch{}的使用方法
2016/12/09 PHP
PHP让数组中有相同值的组成新的数组实例
2017/12/31 PHP
JavaScript 判断日期格式是否正确的实现代码
2011/07/04 Javascript
js遍历、动态的添加数据的小例子
2013/06/22 Javascript
JS图片根据鼠标滚动延时加载的实例代码
2013/07/13 Javascript
node.js WEB开发中图片验证码的实现方法
2014/06/03 Javascript
谷歌浏览器调试JavaScript小技巧
2014/12/29 Javascript
在浏览器中实现图片粘贴的jQuery插件-- pasteimg使用指南
2014/12/29 Javascript
jQuery实现切换字体大小的方法
2015/03/10 Javascript
Javascript的无new构建实例详解
2016/05/15 Javascript
老生常谈的跨域处理
2017/01/11 Javascript
JavaScript函数柯里化原理与用法分析
2017/03/31 Javascript
详谈js对url进行编码和解码(三种方式的区别)
2017/08/16 Javascript
详解react-redux插件入门
2018/04/19 Javascript
React中嵌套组件与被嵌套组件的通信过程
2018/07/11 Javascript
Nuxt配合Node在实际生产中的应用详解
2018/08/07 Javascript
解决vue-router 二级导航默认选中某一选项的问题
2019/11/01 Javascript
vue 实现LED数字时钟效果(开箱即用)
2019/12/08 Javascript
使用python搭建Django应用程序步骤及版本冲突问题解决
2013/11/19 Python
Python字符串中查找子串小技巧
2015/04/10 Python
python协程用法实例分析
2015/06/04 Python
利用selenium爬虫抓取数据的基础教程
2019/06/10 Python
Python中PyQt5/PySide2的按钮控件使用实例
2019/08/17 Python
浅析Django 接收所有文件,前端展示文件(包括视频,文件,图片)ajax请求
2020/03/09 Python
python pandas dataframe 去重函数的具体使用
2020/07/20 Python
软件测试题目
2013/02/27 面试题
信息员培训方案
2014/06/12 职场文书
班级文化标语
2014/06/23 职场文书
党员评议个人总结
2014/10/20 职场文书
2016年学校禁毒宣传活动工作总结
2016/04/05 职场文书
Go标准容器之Ring的使用说明
2021/05/05 Golang
人物搭配车车超萌联名预备中 【咒术迴战】 ⨯ 【天竺鼠车车】 展开合作
2022/04/11 日漫