理解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 相关文章推荐
JQuery 学习笔记 选择器之一
Jul 23 Javascript
判断目标是否是window,document,和拥有tagName的Element的代码
May 31 Javascript
javascript的正则匹配方法学习
Feb 24 Javascript
jQuery实现的多滑动门,多选项卡效果代码
Mar 28 Javascript
详解jQuery中的事件
Dec 14 Javascript
js实现下一页页码效果
Mar 07 Javascript
JS switch判断 三目运算 while 及 属性操作代码
Sep 03 Javascript
动手写一个angular版本的Message组件的方法
Dec 16 Javascript
vue-cli中使用高德地图的方法示例
Mar 28 Javascript
vue spa应用中的路由缓存问题与解决方案
May 31 Javascript
JavaScript代码异常监控实现过程详解
Feb 17 Javascript
vue实现列表垂直无缝滚动
Apr 08 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垃圾回收机制简单说明
2010/07/22 PHP
PHP连接MongoDB示例代码
2012/09/06 PHP
PHP is_subclass_of函数的一个BUG和解决方法
2014/06/01 PHP
php+mysql实现用户注册登陆的方法
2015/01/03 PHP
JObj预览一个JS的框架
2008/03/13 Javascript
JavaScript高级程序设计 阅读笔记(十八) js跨平台的事件
2012/08/14 Javascript
jquery异步跨域访问代码
2013/06/28 Javascript
JS继承用法实例分析
2015/02/05 Javascript
JavaScript实现常用二级省市级联下拉列表的方法
2015/03/25 Javascript
js判断上传文件后缀名是否合法
2016/01/28 Javascript
JavaScript第一篇之实现按钮全选、功能
2016/08/21 Javascript
基于angular中的重要指令详解($eval,$parse和$compile)
2016/10/21 Javascript
DataTables+BootStrap组合使用Ajax来获取数据并且动态加载dom的方法(排序,过滤,分页等)
2016/11/09 Javascript
详解vue的数据binding绑定原理
2017/04/12 Javascript
Angular.JS通过指令操作DOM的方法
2017/05/10 Javascript
AngularJS 控制器 controller的详解
2017/10/17 Javascript
Vue+mui实现图片的本地缓存示例代码
2018/05/24 Javascript
javascript中floor使用方法总结
2019/02/02 Javascript
详解如何运行vue项目
2019/04/15 Javascript
JS随机密码生成算法
2019/09/23 Javascript
vue 使用vant插件做tabs切换和无限加载功能的实现
2020/11/04 Javascript
[01:30]我们共输赢 完美世界城市挑战赛开启全新赛季
2019/04/19 DOTA
Python的Django框架中模板碎片缓存简介
2015/07/24 Python
如何准确判断请求是搜索引擎爬虫(蜘蛛)发出的请求
2015/10/13 Python
今天 平安夜 Python 送你一顶圣诞帽 @微信官方
2017/12/25 Python
python+selenium打印当前页面的titl和url方法
2018/06/22 Python
Python实现JS解密并爬取某音漫客网站
2020/10/23 Python
美国伊甸园兄弟种子公司:Eden Brothers
2018/07/01 全球购物
法国一家芭蕾舞鞋公司:Repetto
2018/11/12 全球购物
西班牙在线宠物食品和配件商店:bitiba
2019/10/11 全球购物
一名女生的自荐信
2013/12/08 职场文书
大学生旅游业创业计划书
2014/01/29 职场文书
银行柜员求职自荐书
2014/06/18 职场文书
入党现实表现材料
2014/12/23 职场文书
鉴史问廉观后感
2015/06/10 职场文书
写给同事的离职感言
2015/08/04 职场文书