理解Javascript_11_constructor实现原理


Posted in Javascript onOctober 18, 2010

constructor是什么

简单的理解,constructor指的就是对象的构造函数。请看如下示例:

function Foo(){}; 
var foo = new Foo(); 
alert(foo.constructor);//Foo 
alert(Foo.constructor);//Function 
alert(Object.constructor);//Function 
alert(Function.constructor);//Function

对于foo.constructor为Foo,我想应该很好理解,因为foo的构造函数为Foo。对于Foo、Object、Function的构造函数为Function,我想也没什么好争议的。(因为Foo,Object,Function都是函数对象,又因为所有的函数对象都是Function这个函数对象构造出来,所以它们的constructor为Function,详细请参考《js_函数对象》)

Prototype与Constructor的关系

function Dog(){} 
alert(Dog === Dog.prototype.constructor);//true

在 JavaScript 中,每个函数都有名为“prototype”的属性,用于引用原型对象。此原型对象又有名为“constructor”的属性,它反过来引用函数本身。这是一种循环引用,如图:
理解Javascript_11_constructor实现原理
constructor属性来自何方
我们来看一下Function构造String的构造过程:
理解Javascript_11_constructor实现原理
注:Function构造任何函数对象的过程都是一样的,所以说不管是String,Boolean,Number等内置对象,还是用户自定义对象,其构造过程都和上图一样。这里String只是一个代表而矣!
图中可以看出constructor是Function在创建函数对象时产生的,也正如'prototype与constructor的关系'中讲的那样,constructor是函数对象prototype链中的一个属性。即String=== String.prototype.constructor。

我还想用一段代码来证明一下,理论是正确的:

function Person(){} 
var p = new Person(); 
alert(p.constructor);//Person 
alert(Person.prototype.constructor);//Person 
alert(Person.prototype.hasOwnProperty('constructor'));//true 
alert(Person.prototype.isPrototypeOf(p));//true 
alert(Object.prototype.isPrototypeOf(p));//true 
alert(Person.prototype == Object.prototype);//false

到现在,你会发现这和前面《原型链的实现原理》中的默认prototype指向Object.prototype有冲突,显然当时的理论不是很全面。

特别的Object
用心的读者可能会提出这样一问题,你这一套理论并不能适用于Object。因为以下的代码和你上面的理论是冲突的:

alert(Object.prototype.hasOwnProperty('constructor'));//true 
alert(Object.prototype.hasOwnProperty('isPrototypeOf'));//true,如果按上面的理论,这里应该返回false

真的是这样吗?不是!那我们来看一下特殊的Object是如何处理的:
理解Javascript_11_constructor实现原理
你会发现,这图的原理和上面一张图的原理是一样的。这就能正确解释Object.prototype.hasOwnProperty('isPrototypeOf')为true!

constructor探究

function Animal(){} 
function Person(){} 
var person = new Person(); 
alert(person.constructor); //Person

根据上一节的内容,你能正确的理解这段代码的结果吗?思考后,看一下其内存表示:
理解Javascript_11_constructor实现原理
这张图明确有表明了Function构造Animal和Person的过程。同时也显示了实例person与Person的关系。

再深入一点,代码如下:

function Animal(){} 
function Person(){} 
Person.prototype = new Animal(); 
var person = new Person(); 
alert(person.constructor); //Animal

这个时候,person的构造函数成了Animal,怎么解释?
理解Javascript_11_constructor实现原理
注:图中的虚线表示Person默认的prototype指向(只作参考的作用)。但是我们将Person.prototype指向了new Animal。
此时,Person的prototype指向的是Animal的实例,所以person的constructor为Animal这个构造函数。

结论:constructor的原理非常简单,就是在对象的原型链上寻找constructor属性。

注:如果你无法正确理解本文内容,请回顾前面章节的内容。

Javascript 相关文章推荐
javascript eval函数深入认识
Feb 21 Javascript
jQuery 位置函数offset,innerWidth,innerHeight,outerWidth,outerHeight,scrollTop,scrollLeft
Mar 23 Javascript
JS+CSS实现一个气泡提示框
Aug 18 Javascript
js判断checkbox是否选中个数的方法(超简单)
Aug 19 Javascript
javascript判断元素存在和判断元素存在于实时的dom中的方法
Jan 17 Javascript
vue 封装自定义组件之tabal列表编辑单元格组件实例代码
Sep 07 Javascript
vue+webpack实现异步组件加载的方法
Feb 03 Javascript
详解浏览器缓存和webpack缓存配置
Jul 06 Javascript
jQuery 图片查看器插件 Viewer.js用法简单示例
Apr 04 jQuery
基于Ionic3实现选项卡切换并重新加载echarts
Sep 24 Javascript
jQuery实现放大镜案例
Oct 19 jQuery
详解Vue3使用axios的配置教程
Apr 29 Vue.js
关于js中window.location.href,location.href,parent.location.href,top.location.href的用法与区别
Oct 18 #Javascript
jQuery Validation实例代码 让验证变得如此容易
Oct 18 #Javascript
jQuery 验证插件 Web前端设计模式(asp.net)
Oct 17 #Javascript
基本jquery的控制tabs打开的数量的代码
Oct 17 #Javascript
Javascript表达式中连续的 && 和 || 之赋值区别
Oct 17 #Javascript
Javascript读取cookie函数代码
Oct 16 #Javascript
JavaScript 拾碎[三] 使用className属性
Oct 16 #Javascript
You might like
php面向对象的方法重载两种版本比较
2008/09/08 PHP
Prototype使用指南之base.js
2007/01/10 Javascript
js如何实现设计模式中的模板方法
2013/07/23 Javascript
用JS做的简单的可折叠的两级树形菜单
2013/09/21 Javascript
随鼠标上下滚动的jquery代码
2013/12/05 Javascript
Angularjs中的页面访问权限怎么设置
2016/11/11 Javascript
解决canvas画布使用fillRect()时高度出现双倍效果的问题
2017/08/03 Javascript
Vue2.0权限树组件实现代码
2017/08/29 Javascript
sublime text配置node.js调试(图文教程)
2017/11/23 Javascript
通过seajs实现JavaScript的模块开发及按模块加载
2019/06/06 Javascript
js设置鼠标悬停改变背景色实现详解
2019/06/26 Javascript
vue路由切换之淡入淡出的简单实现
2019/10/31 Javascript
nodemon实现Typescript项目热更新的示例代码
2019/11/19 Javascript
Nodejs + Websocket 指定发送及群聊的实现
2020/01/09 NodeJs
JavaScript中break、continue和return的用法区别实例分析
2020/03/02 Javascript
Vue-router编程式导航的两种实现代码
2021/03/04 Vue.js
在服务器端实现无间断部署Python应用的教程
2015/04/16 Python
Python之使用adb shell命令启动应用的方法详解
2019/01/07 Python
对python PLT中的image和skimage处理图片方法详解
2019/01/10 Python
django 通过url实现简单的权限控制的例子
2019/08/16 Python
Django stark组件使用及原理详解
2019/08/22 Python
Python+OpenCV实现旋转文本校正方式
2020/01/09 Python
python计算Content-MD5并获取文件的Content-MD5值方式
2020/04/03 Python
基于python实现简单网页服务器代码实例
2020/09/14 Python
python3中celery异步框架简单使用+守护进程方式启动
2021/01/20 Python
西班牙在线光学:Visual-Click
2020/06/22 全球购物
说出你对remoting 和webservice的理解和应用
2014/06/08 面试题
食堂员工工作职责
2013/12/18 职场文书
药品业务员岗位职责
2014/04/17 职场文书
信访工作经验交流材料
2014/05/23 职场文书
红领巾心向党演讲稿
2014/09/10 职场文书
2014年学习全国道德模范事迹思想汇报
2014/09/15 职场文书
公司证明怎么写
2014/09/22 职场文书
三峡人家导游词
2015/01/31 职场文书
孔繁森观后感
2015/06/10 职场文书
go web 预防跨站脚本的实现方式
2021/06/11 Golang