深入分析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 相关文章推荐
制作特殊字的脚本
Jun 26 Javascript
jQuery 入门讲解1
Apr 15 Javascript
javascript中input中readonly和disabled区别介绍
Oct 23 Javascript
javascript中clone对象详解
Dec 03 Javascript
JavaScript 常见安全漏洞和自动化检测技术
Aug 21 Javascript
JavaScript实现获取某个元素相邻兄弟节点的prev与next方法
Jan 25 Javascript
Active控件问题小结(附解决办法)
Jun 09 Javascript
详解Javascript数据类型的转换规则
Dec 12 Javascript
vue生命周期的探索
Apr 03 Javascript
vue实现文字加密功能
Sep 27 Javascript
简单了解vue 插值表达式Mustache
Jul 22 Javascript
vue3弹出层V3Popup实例详解
Jan 04 Vue.js
浅谈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强制类型转换,慎用!
2013/06/06 PHP
php递归遍历删除文件的方法
2015/04/17 PHP
php实现表单多按钮提交action的处理方法
2015/10/24 PHP
浅析PHP中call user func()函数及如何使用call user func调用自定义函数
2015/11/05 PHP
yii2.0整合阿里云oss删除单个文件的方法
2017/09/19 PHP
PHP自动载入类文件函数__autoload的使用方法
2019/03/25 PHP
javascript 网页跳转的方法
2008/12/24 Javascript
一个JQuery操作Table的代码分享
2012/03/30 Javascript
jqGrid读取选择的多行的某个属性代码
2014/05/18 Javascript
JS+CSS实现的日本门户网站经典选项卡导航效果
2015/09/27 Javascript
基于jQuery实现自动轮播旋转木马特效
2015/11/02 Javascript
jQuery向父辈遍历的简单方法
2016/09/18 Javascript
微信小程序(应用号)简单实例应用及实例详解
2016/09/26 Javascript
JavaScript中从setTimeout与setInterval到AJAX异步
2017/02/13 Javascript
node.js中实现kindEditor图片上传功能的方法教程
2017/04/26 Javascript
获取本机IP地址的实例(JavaScript / Node.js)
2017/11/24 Javascript
微信小程序基于本地缓存实现点赞功能的方法
2017/12/18 Javascript
Vue实现todolist删除功能
2018/06/26 Javascript
小程序转发探索示例
2019/02/19 Javascript
详解Vue 全局变量,局部变量
2019/04/17 Javascript
Smartour 让网页导览变得更简单(推荐)
2019/07/19 Javascript
JavaScript闭包原理与用法学习笔记
2020/05/29 Javascript
详解Vue.js3.0 组件是如何渲染为DOM的
2020/11/10 Javascript
[01:12]DOTA2次级职业联赛 - Newbee.Y 战队宣传片
2014/12/01 DOTA
详解python string类型 bytes类型 bytearray类型
2017/12/16 Python
Python打印输出数组中全部元素
2018/03/13 Python
Linux下通过python获取本机ip方法示例
2019/09/06 Python
美国钻石商店:Zales
2016/11/20 全球购物
高三历史教学反思
2014/01/09 职场文书
中秋节超市促销方案
2014/01/30 职场文书
道德之星事迹材料
2014/05/03 职场文书
运动会演讲稿50字
2014/08/25 职场文书
寒暑假实习证明书模板
2014/11/29 职场文书
幼儿园教师求职信
2015/03/20 职场文书
Java 在线考试云平台的实现
2021/11/23 Java/Android
win10壁纸在哪个文件夹 win10桌面背景图片文件位置分享
2022/08/05 数码科技