深入分析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 相关文章推荐
JavaScript基本对象
Jan 11 Javascript
datagrid框架的删除添加与修改
Apr 08 Javascript
jquery DIV撑大让滚动条滚到最底部代码
Jun 06 Javascript
jquery重复提交请求的原因浅析
May 23 Javascript
JavaScript实现向OL列表内动态添加LI元素的方法
Mar 21 Javascript
jquery+css实现绚丽的横向二级下拉菜单-附源码下载
Aug 23 Javascript
深入理解js generator数据类型
Aug 16 Javascript
Bootstrap的class样式小结
Dec 01 Javascript
Angular的$http的ajax的请求操作(推荐)
Jan 10 Javascript
Javascript继承机制详解
May 30 Javascript
Nuxt升级2.0.0时出现的问题(小结)
Oct 08 Javascript
layer.alert自定义关闭回调事件的方法
Sep 27 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
在数据量大(超过10万)的情况下
2007/01/15 PHP
解析php中static,const与define的使用区别
2013/06/18 PHP
php+mysql实现无限分类实例详解
2015/01/15 PHP
php实现在多维数组中查找特定value的方法
2015/07/29 PHP
php实现保存周期为1天的购物车类
2017/07/07 PHP
php-msf源码详解
2017/12/25 PHP
jquery实现metro效果示例代码
2013/09/06 Javascript
jquery实现简单的表单验证
2015/11/17 Javascript
详解AngularJS过滤器的使用
2016/03/11 Javascript
基于jQuery实现音乐播放试听列表
2016/04/14 Javascript
Angular2中Bootstrap界面库ng-bootstrap详解
2016/10/18 Javascript
jquery实现(textarea)placeholder自动换行
2016/12/22 Javascript
jQuery插件FusionCharts绘制的3D饼状图效果实例【附demo源码下载】
2017/03/03 Javascript
react开发中如何使用require.ensure加载es6风格的组件
2017/05/09 Javascript
AngularJS实现页面跳转后自动弹出对话框实例代码
2017/08/02 Javascript
静态页面实现 include 引入公用代码的示例
2017/09/25 Javascript
JS实现定时任务每隔N秒请求后台setInterval定时和ajax请求问题
2017/10/15 Javascript
基于模板引擎Jade的应用(详解)
2017/12/12 Javascript
iview table高度动态设置方法
2018/03/14 Javascript
微信小程序实现滴滴导航tab切换效果
2018/07/24 Javascript
在Python中使用zlib模块进行数据压缩的教程
2015/06/26 Python
100行Python代码实现自动抢火车票(附源码)
2018/01/11 Python
python+numpy+matplotalib实现梯度下降法
2018/08/31 Python
详解Python3除法之真除法、截断除法和下取整对比
2019/05/23 Python
python实现发送QQ邮件(可加附件)
2020/12/23 Python
全球酒店预订网站:Hotels.com
2016/08/10 全球购物
linux面试题参考答案(7)
2014/07/24 面试题
幼儿园安全检查制度
2014/01/30 职场文书
普通话演讲稿
2014/09/03 职场文书
综治工作心得体会
2014/09/11 职场文书
春风化雨观后感
2015/06/11 职场文书
公司食堂管理制度
2015/08/05 职场文书
宾馆客房管理制度
2015/08/06 职场文书
入党申请书格式
2019/06/20 职场文书
SQLServer 错误: 15404,无法获取有关 Windows NT 组/用户 WIN-8IVSNAQS8T7\Administrator 的信息
2021/06/30 SQL Server
电脑无法安装Windows 11怎么办?无法安装Win11的解决方法
2021/11/21 数码科技