深入分析js中的constructor和prototype


Posted in Javascript onApril 07, 2012

我们在定义函数的时候,函数定义的时候函数本身就会默认有一个prototype的属性,而我们如果用new 运算符来生成一个对象的时候就没有prototype属性。我们来看一个例子,来说明这个

function a(c){ 
this.b = c; 
this.d =function(){ 
alert(this.b); 
} 
} 
var obj = new a('test'); 
alert(typeof obj.prototype);//undefine 
alert(typeof a.prototype);//object

从上面的例子可以看出函数的prototype 属性又指向了一个对象,这个对象就是prototype对象,请看下图

深入分析js中的constructor和prototype

a.prototype 包含了2个属性,一个是constructor ,另外一个是__proto__

这个constructor  就是我们的构造函数a,这个也很容易理解。

那么__proto__ 是什么呢?

这个就涉及到了原型链的概念:

每个对象都会在其内部初始化一个属性,就是__proto__,当我们访问一个对象的属性 时,如果这个对象内部不存在这个属性,那么他就会去__proto__里找这个属性,这个__proto__又会有自己的__proto__,于是就这样 一直找下去。

请看mozzlia 对它对它的描述

When an object is created, its __proto__ property is set to constructing function's prototype property. For example var fred = new Employee(); will cause fred.__proto__ = Employee.prototype;.

This is used at runtime to look up properties which are not declared in the object directly. E.g. when fred.doSomething() is executed and fred does not contain adoSomethingfred.__proto__ is checked, which points to Employee.prototype, which contains a doSomething, i.e. fred.__proto__.doSomething() is invoked.

Note that __proto__ is a property of the instances, whereas prototype is a property of their constructor functions.

不管你信不信,我们来看图

深入分析js中的constructor和prototype
在后面如果加上 alert(obj.__proto__ === a.prototype) //true

同理,在这里我们来分析出new 运算符做了那些事情

  1.  var obj={}; 也就是说,初始化一个对象obj。
  2. obj.__proto__=a.prototype;
  3.  a.call(obj);也就是说构造obj,也可以称之为初始化obj。

我们将这个例子改造一些,变得复杂一点。

function a(c){ 
this.b = c; 
this.d =function(){ 
alert(this.b); 
} 
} 
a.prototype.test = function(){ 
alert(this.b); 
} 
var obj = function (){} 
obj.prototype = new a('test'); 
obj.prototype.test1 =function(){ 
alert(22222); 
} 
var t = new obj('test'); 
t.test();//alert('test');

我们来分析下这个过程

由 var t = new obj('test'); 我们可以得到 t.__proto__ = obj.prototype,但是上面指定obj.prototype =new a('test'); 可以这样来看下

obj.prototype = p, p = new a('test'); p.__proto__ = a.prototype;

那么obj.prototype.__proto__ = a.prototype,由 t.__proto__ = obj.prototype 可以得出 t.__proto__.__proto__ = a.prototype,

所以对象t先去找本身是的prototype 是否有test函数,发现没有,结果再往上级找,即 t.__proto__ ,亦即obj.prototype 寻找test函数 ,但是obj.prototype 也没有这个函数,然后再往上找。即

t.__proto__.__proto__ 找,由于t.__proto__.__proto__ = a.prototype 在 a.prototype 中找到了这个方法,输出了alert('test')

从这里可以分析得出一个结论,js中原形链的本质在于 __proto__

再看看一个列子

function a(c){ 
this.b = c; 
this.d =function(){ 
alert(this.b); 
} 
} 
var obj = new a('test'); 
alert(obj.constructor);//function a(){} 
alert(a.prototype.constructor);//function a(){}

根据上面讲到的__proto__ 我们来分析下,首先obj是没有constructor 这个属性的,但是 obj.__proto__ = a.prototype;就从

a.prototype中寻找,而 a.prototype.constructor 是就a,所有两者的结果是一一样的.

Javascript 相关文章推荐
FileUpload上传图片(图片不变形)
Aug 05 Javascript
多浏览器兼容性比较好的复制到剪贴板的js代码
Oct 09 Javascript
jQuery制作仿Mac Lion OS滚动条效果
Feb 10 Javascript
WordPress 单页面上一页下一页的实现方法【附代码】
Mar 10 Javascript
jQuery on()方法绑定动态元素的点击事件无响应的解决办法
Jul 07 Javascript
jQuery mobile在页面加载时添加加载中效果 document.ready 和window.onload执行顺序比较
Jul 14 Javascript
jQuery内容过滤选择器用法示例
Sep 09 Javascript
angularJS深拷贝详解
Mar 23 Javascript
Express使用html模板的详细代码
Sep 18 Javascript
vue.js template模板的使用(仿饿了么布局)
Aug 13 Javascript
vue父子组件间引用之$parent、$children
May 20 Javascript
vue+elementui实现点击table中的单元格触发事件--弹框
Jul 18 Javascript
浅谈javascript中的作用域
Apr 07 #Javascript
JavaScript 高级篇之DOM文档,简单封装及调用、动态添加、删除样式(六)
Apr 07 #Javascript
JavaScript 高级篇之闭包、模拟类,继承(五)
Apr 07 #Javascript
JavaScript 高级篇之函数 (四)
Apr 07 #Javascript
JavaScript 基础篇之对象、数组使用介绍(三)
Apr 07 #Javascript
JavaScript 基础篇之运算符、语句(二)
Apr 07 #Javascript
为原生js Array增加each方法
Apr 07 #Javascript
You might like
php文件上传的例子及参数详解
2013/12/12 PHP
javascript实现的listview效果
2007/04/28 Javascript
建立良好体验度的Web注册系统ajax
2007/07/09 Javascript
日历查询的算法 如何计算某一天是星期几
2012/12/12 Javascript
ExpressJS入门实例
2015/01/14 Javascript
JS实现弹出浮动窗口(支持鼠标拖动和关闭)实例详解
2015/08/06 Javascript
easyui Droppable组件实现放置特效
2015/08/19 Javascript
JS实现仿QQ效果的三级竖向菜单
2015/09/25 Javascript
ES6新特性之变量和字符串用法示例
2017/04/01 Javascript
javascript帧动画(实例讲解)
2017/09/02 Javascript
浅谈vue项目如何打包扔向服务器
2018/05/08 Javascript
vue使用监听实现全选反选功能
2018/07/06 Javascript
解决Vue中引入swiper,在数据渲染的时候,发生不滑动的问题
2018/09/27 Javascript
jQuery时间戳和日期相互转换操作示例
2018/12/07 jQuery
使用Phantomjs和Node完成网页的截屏快照的方法
2019/07/16 Javascript
VUE实现移动端列表筛选功能
2019/08/23 Javascript
基于js实现抽红包并分配代码实例
2019/09/19 Javascript
生成无限制的微信小程序码的示例代码
2019/09/20 Javascript
Vue修改项目启动端口号方法
2019/11/07 Javascript
纯JS开发baguetteBox.js响应式画廊插件
2020/06/28 Javascript
jQuery实现移动端扭蛋机抽奖
2020/11/08 jQuery
[04:22]DOTA2大事件之护国神翼
2020/08/14 DOTA
六个窍门助你提高Python运行效率
2015/06/09 Python
Python os模块学习笔记
2015/06/21 Python
Python程序中的观察者模式结构编写示例
2016/05/27 Python
python获取文件路径、文件名、后缀名的实例
2018/04/23 Python
python实现随机漫步算法
2018/08/27 Python
对python3 sort sorted 函数的应用详解
2019/06/27 Python
使用虚拟环境打包python为exe 文件的方法
2019/08/29 Python
pycharm中import呈现灰色原因的解决方法
2020/03/04 Python
Python sorted对list和dict排序
2020/06/09 Python
小学教师的自我评价范例
2013/10/31 职场文书
法学求职信
2014/06/22 职场文书
2014年实验室工作总结
2014/12/03 职场文书
公司员工离职感言
2015/08/03 职场文书
MySQL运行报错:“Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggre”解决方法
2022/06/14 MySQL