深入分析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 相关文章推荐
解决AJAX中跨域访问出现'没有权限'的错误
Aug 20 Javascript
网页右下角弹出窗体实现代码
Jun 05 Javascript
node.js中的fs.lchownSync方法使用说明
Dec 16 Javascript
JavaScript代码实现禁止右键、禁选择、禁粘贴、禁shift、禁ctrl、禁alt
Nov 17 Javascript
Javascript removeChild()删除节点及删除子节点的方法
Dec 27 Javascript
基于jquery实现瀑布流布局
Jun 28 Javascript
一个非常好用的文字滚动的案例,鼠标悬浮可暂停[两种方案任选]
Dec 01 Javascript
js实现textarea限制输入字数
Feb 13 Javascript
Javascript 链式作用域详细介绍
Feb 23 Javascript
js数组去重的N种方法(小结)
Jun 07 Javascript
Vue基本使用之对象提供的属性功能
Apr 30 Javascript
全面解析JavaScript Module模式
Jul 24 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
星际初学者游戏中永远要做的事
2020/03/04 星际争霸
新手学PHP之数据库操作详解及乱码解决!
2007/01/02 PHP
PHP中遇到的时区问题解决方法
2015/07/23 PHP
简单实现php上传文件功能
2017/09/21 PHP
jquery控制listbox中项的移动并排序的实现代码
2010/09/28 Javascript
html5的自定义data-*属性和jquery的data()方法的使用示例
2013/08/21 Javascript
javascript 循环调用示例介绍
2013/11/20 Javascript
深入分析JQuery和JavaScript的异同
2014/10/23 Javascript
JavaScript的模块化开发框架Sea.js上手指南
2016/05/12 Javascript
JavaScript对象创建模式实例汇总
2016/10/03 Javascript
Angular.js中用ng-repeat-start实现自定义显示
2016/10/18 Javascript
JS匿名函数实例分析
2016/11/26 Javascript
用nodeJS搭建本地文件服务器的几种方法小结
2017/03/16 NodeJs
JavaScript数据结构之双向链表和双向循环链表的实现
2017/11/28 Javascript
JS实现运动缓冲效果的封装函数示例
2018/02/18 Javascript
vue调用语音播放的方法
2019/09/27 Javascript
微信小程序背景音乐开发详解
2019/12/12 Javascript
Jquery Datatables的使用详解
2020/01/30 jQuery
vue 实现超长文本截取,悬浮框提示
2020/07/29 Javascript
vue中template的三种写法示例
2020/10/21 Javascript
[02:48]DOTA2超级联赛专访海涛:你们的选择没有错
2013/06/07 DOTA
python实现定时同步本机与北京时间的方法
2015/03/24 Python
使用pyecharts无法import Bar的解决方案
2020/04/23 Python
Python算法应用实战之栈详解
2017/02/04 Python
Python实现句子翻译功能
2017/11/14 Python
python数据持久存储 pickle模块的基本使用方法解析
2019/08/30 Python
tensorflow之自定义神经网络层实例
2020/02/07 Python
Windows下PyCharm配置Anaconda环境(超详细教程)
2020/07/31 Python
利用Pycharm + Django搭建一个简单Python Web项目的步骤
2020/10/22 Python
基于CSS3制作立体效果导航菜单
2016/01/12 HTML / CSS
HTML5引入的新数组TypedArray介绍
2012/12/24 HTML / CSS
求职自荐信格式
2013/12/04 职场文书
班级旅游计划书
2014/05/03 职场文书
党员干部四风问题整改措施思想汇报
2014/10/12 职场文书
电影建国大业观后感
2015/06/01 职场文书
Python如何导出导入所有依赖包详解
2021/06/08 Python