深入分析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 YUI 读码日记之 YAHOO.util.Dom - Part.2 0
Mar 22 Javascript
Javascript load Page,load css,load js实现代码
Mar 31 Javascript
比Jquery的document.ready更快的方法
Apr 28 Javascript
Array.prototype.slice 使用扩展
Jun 09 Javascript
用js编写的简单的计算器代码程序
Aug 04 Javascript
jQuery获取及设置表单input各种类型值的方法小结
May 24 Javascript
JS图片放大效果简单实现代码
Sep 08 Javascript
BootStrap入门教程(二)之固定的内置样式
Sep 19 Javascript
自己封装的一个原生JS拖动方法(推荐)
Nov 22 Javascript
js addDqmForPP给标签内属性值加上双引号的函数
Dec 24 Javascript
微信小程序自定义底部导航带跳转功能
Nov 27 Javascript
JS实现按比例缩小图片宽高
Aug 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
基于PHP实现用户注册登录功能
2016/10/14 PHP
PHP7内核之Reference详解
2019/03/14 PHP
javascript编程起步(第六课)
2007/01/10 Javascript
jQuery语法高亮插件支持各种程序源代码语法着色加亮
2013/04/27 Javascript
微信企业号开发之微信考勤Cookies的使用
2015/09/11 Javascript
jQuery实现多级联动下拉列表查询框
2016/01/18 Javascript
JS排序方法(sort,bubble,select,insert)代码汇总
2016/01/30 Javascript
基于Javascript实现二级联动菜单效果
2016/03/04 Javascript
DWR中各种java方法的调用
2016/05/04 Javascript
深入理解nodejs中Express的中间件
2017/05/19 NodeJs
vue单页应用中如何使用jquery的方法示例
2017/07/27 jQuery
node.js 用socket实现聊天的示例代码
2017/10/17 Javascript
VUE前端cookie简单操作
2017/10/17 Javascript
JS实现的简单拖拽购物车功能示例【附源码下载】
2018/01/03 Javascript
解决循环中setTimeout执行顺序的问题
2018/06/20 Javascript
js+canvas实现验证码功能
2020/09/21 Javascript
vue 集成jTopo 处理方法
2019/08/07 Javascript
javascript实现简易计算器功能
2020/09/23 Javascript
[05:01]3.19DOTA2发布会 我们都是刀塔人
2014/03/25 DOTA
[02:12]探秘2016国际邀请赛中国区预选赛选手房间
2016/06/25 DOTA
Python实现动态添加类的属性或成员函数的解决方法
2014/07/16 Python
举例介绍Python中的25个隐藏特性
2015/03/30 Python
vue.js实现输入框输入值内容实时响应变化示例
2018/07/07 Python
Python 类,property属性(简化属性的操作),@property,property()用法示例
2019/10/12 Python
python 将html转换为pdf的几种方法
2020/12/29 Python
CSS3 box-sizing属性
2009/04/17 HTML / CSS
警察思想汇报
2014/01/04 职场文书
环保专项行动方案
2014/05/12 职场文书
区域经理岗位职责
2015/02/02 职场文书
测量员岗位职责
2015/02/14 职场文书
校园运动会广播稿
2015/08/19 职场文书
新手,如何业余时间安排好写作、提高写作能力?
2019/10/21 职场文书
Python连续赋值需要注意的一些问题
2021/06/03 Python
logback 实现给变量指定默认值
2021/08/30 Java/Android
MySQL高级进阶sql语句总结大全
2022/03/16 MySQL
Android开发EditText禁止输入监听及InputFilter字符过滤
2022/06/10 Java/Android