深入分析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+css 网页每次加载不同样式的实现方法
Dec 27 Javascript
在js文件中如何获取basePath处理js路径问题
Jul 10 Javascript
js动态设置鼠标事件示例代码
Oct 30 Javascript
JavaScript在网页中画圆的函数arc使用方法
Nov 13 Javascript
jQuery实现验证年龄简单思路
Feb 24 Javascript
JQuery中attr属性和jQuery.data()学习笔记【必看】
May 18 Javascript
JavaScript读二进制文件并用ajax传输二进制流的方法
Jul 18 Javascript
Google 地图类型详解及示例代码
Aug 06 Javascript
利用jquery正则表达式在页面验证url网址输入是否正确
Apr 04 jQuery
React性能优化系列之减少props改变的实现方法
Jan 17 Javascript
基于Vue.js与WordPress Rest API构建单页应用详解
Sep 16 Javascript
解决LayUI数据表格复选框不居中显示的问题
Sep 25 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给图片加文字水印
2015/07/31 PHP
php实现概率性随机抽奖代码
2016/01/02 PHP
golang与php实现计算两个经纬度之间距离的方法
2016/07/22 PHP
PHP+ajax实现获取新闻数据简单示例
2018/05/08 PHP
Extjs4中的分页应用结合前后台
2013/12/13 Javascript
让人蛋疼的JavaScript语法特性
2014/09/30 Javascript
jQuery实现图片与文字描述左右滑动自动切换的方法
2015/07/27 Javascript
AngularJS 使用 UI Router 实现表单向导
2016/01/29 Javascript
js操作数据库实现注册和登陆的简单实例
2016/05/26 Javascript
微信小程序  Mustache语法详细介绍
2016/10/27 Javascript
Angular4 ElementRef的应用
2018/02/26 Javascript
微信小程序上传图片功能(附后端代码)
2020/06/19 Javascript
vue导出html、word和pdf的实现代码
2018/07/31 Javascript
vue cli3.0结合echarts3.0与地图的使用方法示例
2019/03/26 Javascript
微信小程序获取地理位置及经纬度授权代码实例
2019/09/18 Javascript
JS实现简易留言板增删功能
2020/02/08 Javascript
一篇文章带你浅入webpack的DLL优化打包
2020/02/20 Javascript
vue+element使用动态加载路由方式实现三级菜单页面显示的操作
2020/08/04 Javascript
vue+elementui通用弹窗的实现(新增+编辑)
2021/01/07 Vue.js
在Python的web框架中配置app的教程
2015/04/30 Python
Python使用中文正则表达式匹配指定中文字符串的方法示例
2017/01/20 Python
Python实现将照片变成卡通图片的方法【基于opencv】
2018/01/17 Python
解决pip install psycopg2出错问题
2020/07/09 Python
如何使用 Python 读取文件和照片的创建日期
2020/09/05 Python
HTML5重塑Web世界它将如何改变互联网
2012/12/17 HTML / CSS
柏林通行证:Berlin Pass
2018/04/11 全球购物
全球异乡人的跨境社交电商平台:Kouhigh口嗨网
2020/07/24 全球购物
char型变量中能不能存贮一个中文汉字
2015/07/08 面试题
Sony C++笔试题
2013/03/10 面试题
党的群众路线对照检查材料范文
2014/09/24 职场文书
2015年毕业生自荐信范文
2015/03/24 职场文书
春季运动会加油词
2015/07/18 职场文书
小学家庭教育心得体会
2016/01/14 职场文书
护士业务学习心得体会
2016/01/25 职场文书
解决Jupyter-notebook不弹出默认浏览器的问题
2021/03/30 Python
分析MySQL优化 index merge 后引起的死锁
2022/04/19 MySQL