深入分析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 01 Javascript
Javascript的匿名函数小结
Dec 31 Javascript
JavaScript中链式调用之研习
Apr 07 Javascript
浅析JavaScript中的常用算法与函数
Nov 21 Javascript
Node.js如何使用Diffie-Hellman密钥交换算法详解
Sep 05 Javascript
详解如何解决vue开发请求数据跨域的问题(基于浏览器的配置解决)
Nov 12 Javascript
JS实现图片拖拽交换效果
Nov 30 Javascript
微信小程序实现图片滚动效果示例
Dec 05 Javascript
Angular使用Restful的增删改
Dec 28 Javascript
Elasticsearch实现复合查询高亮结果功能
Sep 10 Javascript
使用Karma做vue组件单元测试的实现
Jan 16 Javascript
微信小程序实现点击导航标签滚动定位到对应位置
Nov 19 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源代码数组统计count分析
2011/08/02 PHP
PHP实现更新中间关联表数据的两种方法
2014/09/01 PHP
针对多用户实现头像上传功能PHP代码 适用于登陆页面制作
2016/08/17 PHP
颜色选择器 Color Picker,IE,Firefox,Opera,Safar
2010/11/25 Javascript
跟我学Nodejs(一)--- Node.js简介及安装开发环境
2014/05/20 NodeJs
js实现鼠标滚轮控制图片缩放效果的方法
2015/02/20 Javascript
详谈javascript中的cookie
2015/06/03 Javascript
Ajax清除浏览器js、css、图片缓存的方法
2015/08/06 Javascript
JS留言功能的简单实现案例(推荐)
2016/06/23 Javascript
AngularJS基础 ng-show 指令简单示例
2016/08/03 Javascript
使用bootstrap validator的remote验证代码经验分享(推荐)
2016/09/21 Javascript
javascript入门之string对象【新手必看】
2016/11/22 Javascript
Vue集成Iframe页面的方法示例
2017/12/12 Javascript
Vue 组件传值几种常用方法【总结】
2018/05/28 Javascript
vue的keep-alive用法技巧
2019/08/15 Javascript
浅谈vue-router路由切换 组件重用挖下的坑
2019/11/01 Javascript
原生js实现贪吃蛇游戏
2020/10/26 Javascript
vue切换菜单取消未完成接口请求的案例
2020/11/13 Javascript
elementUI同一页面展示多个Dialog的实现
2020/11/19 Javascript
Python的Flask框架中实现登录用户的个人资料和头像的教程
2015/04/20 Python
编写Python CGI脚本的教程
2015/06/29 Python
python 请求服务器的实现代码(http请求和https请求)
2018/05/25 Python
基于DataFrame改变列类型的方法
2018/07/25 Python
Python遍历字典方式就实例详解
2019/12/28 Python
让IE可以变相支持CSS3选择器
2010/01/21 HTML / CSS
罗德与泰勒百货官网:Lord & Taylor
2016/08/12 全球购物
Superdry极度乾燥官网:日本街头风格,纯英国制造品牌
2016/10/31 全球购物
美国一家全面的在线零售鞋类公司:SHOEBACCA
2017/01/06 全球购物
揠苗助长教学反思
2014/02/04 职场文书
房产继承公证书
2014/04/09 职场文书
《会走路的树》教后反思
2014/04/19 职场文书
厨师长岗位职责范本
2014/08/25 职场文书
公司领导班子四风对照检查材料
2014/09/27 职场文书
学校开除通知书
2015/04/25 职场文书
感谢信的技巧及范例
2019/05/15 职场文书
JavaScript获取URL参数的方法分享
2022/04/07 Javascript