深入分析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 相关文章推荐
读jQuery之一(对象的组成)
Jun 11 Javascript
alert出数组中的随即值代码
Sep 25 Javascript
javascript解析json实例详解
Nov 05 Javascript
jQuery实现大转盘抽奖活动仿QQ音乐代码分享
Aug 21 Javascript
JS实现网页标题栏显示当前时间和日期的完整代码
Nov 02 Javascript
AngularJS Bootstrap详细介绍及实例代码
Jul 28 Javascript
基于javascript实现按圆形排列DIV元素(三)
Dec 02 Javascript
jQuery插件echarts去掉垂直网格线用法示例
Mar 03 Javascript
angular指令笔记ng-options的使用方法
Sep 18 Javascript
vue+iview 兼容IE11浏览器的实现方法
Jan 07 Javascript
Javascript异步流程控制之串行执行详解
Sep 27 Javascript
react antd实现动态增减表单
Jun 03 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大批量插入数据库的3种方法和速度对比
2014/07/08 PHP
WordPress中自定义后台管理界面配色方案的小技巧
2015/12/29 PHP
分析PHP中单双引号的误区和双引号小隐患
2016/07/19 PHP
CI(CodeIgniter)框架视图中加载视图的方法
2017/03/24 PHP
JQuery CSS样式控制 学习笔记
2009/07/23 Javascript
对 jQuery 中 data 方法的误解分析
2014/06/18 Javascript
js实现透明度渐变效果的方法
2015/04/10 Javascript
JavaScript程序开发之JS代码放置的位置
2016/01/15 Javascript
AngularJS中$injector、$rootScope和$scope的概念和关联关系深入分析
2017/01/19 Javascript
js仿新浪微博消息发布功能
2017/02/17 Javascript
使用JS实现图片轮播的实例(前后首尾相接)
2017/09/21 Javascript
Vue 实现双向绑定的四种方法
2018/03/16 Javascript
vue-rx的初步使用教程
2018/09/21 Javascript
微信小程序实现卡片左右滑动效果的示例代码
2019/05/01 Javascript
JavaScript中的各种宽高属性的实现
2020/05/08 Javascript
node使用async_hooks模块进行请求追踪
2021/01/28 Javascript
[00:20]DOTA2荣耀之路7:-ah fu-抢盾
2018/05/31 DOTA
[51:10]VP vs VGJ.S 2018国际邀请赛小组赛BO2 第二场 8.19
2018/08/21 DOTA
[46:59]完美世界DOTA2联赛PWL S2 GXR vs Ink 第二场 11.19
2020/11/20 DOTA
[01:42:49]DOTA2-DPC中国联赛 正赛 iG vs PSG.LGD BO3 第一场 2月26日
2021/03/11 DOTA
详解python中递归函数
2019/04/16 Python
Djang的model创建的字段和参数详解
2019/07/27 Python
Python多线程thread及模块使用实例
2020/04/28 Python
解决IDEA 的 plugins 搜不到任何的插件问题
2020/05/04 Python
python中pdb模块实例用法
2021/01/15 Python
纯CSS3实现手风琴风格菜单具体步骤
2013/05/06 HTML / CSS
PHP如何与mysql建立链接
2013/05/05 面试题
网络管理员岗位职责
2014/03/17 职场文书
《音乐之都维也纳》教学反思
2014/04/16 职场文书
分公司经理任命书
2014/06/05 职场文书
幼儿园教师师德师风承诺书
2015/04/28 职场文书
元宵节晚会主持词
2015/07/01 职场文书
小学英语教学经验交流材料
2015/11/02 职场文书
2016年度农村党员干部主题教育活动总结
2016/04/06 职场文书
导游词之沈阳植物园
2019/11/30 职场文书
redis数据结构之压缩列表
2022/03/21 Redis