理解Javascript_08_函数对象


Posted in Javascript onOctober 15, 2010

函数对象
首先,大家得明确一个概念:函数就是对象,代表函数的对象就是函数对象。既然是对象,那它又是被谁构造出来的呢?下面我们来看一段描述:JavaScript代码中定义函数,或者调用Function创建函数时,最终都会以类似这样的形式调用Function函数:var newFun=Function(funArgs, funBody); 。由此可知函数对象是由Function这个函数对象构造出来的。
注:Function对象本身也是一个函数,因此它也一个函数对象。关于Function的深入理解,请见后续博文。
正面我们来看一段代码:

//定义方式一 
function func(x) { 
alert(x); 
} 
//定义方式二 
var func = function(x) { 
alert(x); 
}; 
//实际执行 
var func = new Function(“x”, “alert(x);”);

通过上面的代码可知,函数func无非是由Function对象接收两个参数后构造出来的而矣!

注:关于定义方式一与定义方式二的区别,请见后续博文

函数对象的创建过程

函数对象详细创建步骤如下:

1. 创建一个build-in object对象fn

2. 将fn的内部[[Prototype]]设为Function.prototype
3. 设置内部的[[Call]]属性,它是内部实现的一个方法,处理函数调用的逻辑。(简单的理解为调用函数体)

4. 设置内部的[[Construct]]属性,它是内部实现的一个方法,处理逻辑参考对象创建过程。(简单的理解为创建对象《理解Javascript_06_理解对象的创建过程》一文)

5. 设置fn.length为funArgs.length,如果函数没有参数,则将fn.length设置为0
6. 使用new Object()同样的逻辑创建一个Object对象fnProto
7. 将fnProto.constructor设为fn
8. 将fn.prototype设为fnProto
9. 返回fn

步骤1跟步骤6的区别为,步骤1只是创建内部用来实现Object对象的数据结构(build-in object structure),并完成内部必要的初始化工作,但它的[[Prototype]]、[[Call]]、[[Construct]]等属性应当为 null或者内部初始化值,即我们可以理解为不指向任何对象(对[[Prototype]]这样的属性而言),或者不包含任何处理(对 [[Call]]、[[Construct]]这样的方法而言)。步骤6则将按照《理解Javascript_06_理解对象的创建过程》创建一个新的对象,它的 [[Prototype]]等被设置了。
从上面的处理步骤可以了解,任何时候我们定义一个函数,它的prototype是一个Object实例,这样默认情况下我们创建自定义函数的实例对象时,它们的Prototype链将指向Object.prototype。

注:Function一个特殊的地方,是它的[[Call]]和[[Construct]]处理逻辑一样。深层次的原因将在后续博文中介绍。

下面我们写一些用例脚本来测试一下上面的理论:

function Animal(){ 
} 
alert(Animal.length);//0 var dog = new Animal();

这个JS证明了步骤5的正确性。最后,还是来看一下函数对象的内存图,简单起见,内存图只描述了Animal的构造过程:
理解Javascript_08_函数对象
来自于一个整体的分析图:
理解Javascript_08_函数对象
图片本身已经能解释很多很多的问题了,结合前面instanceof原理,对象构造原理,原型链原理,自已去体会吧,我就不多说什么了。

其实上Function对象是一个很奇妙的对象,它与Object的关系更是扑朔迷离,我将在《理解Javascript_09_Function与Object》中解释这一切。

最后的声明:理论过于复杂,我不改保证其正确性。但经过多方的测试,还未发现理论与实际冲突的地方。

Javascript 相关文章推荐
javascript解决innerText浏览器兼容问题思路代码
May 17 Javascript
Jquery选择器中使用变量实现动态选择例子
Jul 25 Javascript
关于RequireJS的简单介绍即使用方法
Oct 20 Javascript
微信小程序page的生命周期和音频播放及监听实例详解
Apr 07 Javascript
Node.js中你不可不精的Stream(流)
Jun 08 Javascript
Vue中$refs的用法详解
Jun 24 Javascript
微信小程序中使用Async-await方法异步请求变为同步请求方法
Mar 28 Javascript
一个小时快速搭建微信小程序的方法步骤
Apr 15 Javascript
layer.alert自定义关闭回调事件的方法
Sep 27 Javascript
vue实现信息管理系统
May 30 Javascript
Vue如何将页面导出成PDF文件
Aug 17 Javascript
原生JS实现相邻月份日历
Oct 13 Javascript
javascript instanceof 内部机制探析
Oct 15 #Javascript
理解Javascript_07_理解instanceof实现原理
Oct 15 #Javascript
JavaScript 对象模型 执行模型
Oct 15 #Javascript
理解Javascript_06_理解对象的创建过程
Oct 15 #Javascript
JavaScript聚焦于第一个字段的代码
Oct 15 #Javascript
JavaScript访问样式表代码
Oct 15 #Javascript
IE下js调试工具Companion.JS
Oct 15 #Javascript
You might like
php 数组的创建、调用和更新实现代码
2009/03/09 PHP
PHP 错误之引号中使用变量
2009/05/04 PHP
解析Ubuntu下crontab命令的用法
2013/06/24 PHP
ThinkPHP页面跳转success与error方法概述
2014/06/25 PHP
Yii中实现处理前后台登录的新方法
2015/12/28 PHP
form表单传递数组数据、php脚本接收的实例
2017/02/09 PHP
PHP基于pdo的数据库操作类【可支持mysql、sqlserver及oracle】
2018/05/21 PHP
PHP如何使用array_unshift()在数组开头插入元素
2020/09/01 PHP
神奇的7个jQuery 3D插件整理
2011/01/06 Javascript
使用jquery.upload.js实现异步上传示例代码
2014/07/29 Javascript
根据配置文件加载js依赖模块
2014/12/29 Javascript
卸载安装Node.js与npm过程详解
2016/08/15 Javascript
微信小程序 wxapp内容组件 progress详细介绍
2016/10/31 Javascript
angular过滤器实现排序功能
2017/06/27 Javascript
Mongoose实现虚拟字段查询的方法详解
2017/08/15 Javascript
vue实现选项卡及选项卡切换效果
2018/04/24 Javascript
JS获取当前时间的实例代码(昨天、今天、明天)
2018/11/13 Javascript
在mpvue框架中使用Vant WeappUI组件库的注意事项【推进】
2019/06/09 Javascript
mpvue实现小程序签到金币掉落动画(api实现)
2019/10/17 Javascript
js实现3D照片墙效果
2019/10/28 Javascript
深入理解 TypeScript Reflect Metadata
2019/12/12 Javascript
Python原始字符串与Unicode字符串操作符用法实例分析
2017/07/22 Python
Python编程中NotImplementedError的使用方法
2018/04/21 Python
python射线法判断一个点在图形区域内外
2019/06/28 Python
基于django micro搭建网站实现加水印功能
2020/05/22 Python
Python使用20行代码实现微信聊天机器人
2020/06/05 Python
python中判断文件结束符的具体方法
2020/08/04 Python
python super()函数的基本使用
2020/09/10 Python
新秀丽拉杆箱美国官方网站:Samsonite美国
2016/07/25 全球购物
教师个人的自我评价分享
2014/01/02 职场文书
家庭教育先进个人事迹材料
2014/01/24 职场文书
高中生班主任评语
2014/04/25 职场文书
2015年世界无烟日活动方案
2015/05/04 职场文书
劳动争议仲裁代理词
2015/05/25 职场文书
酒店厨房管理制度
2015/08/06 职场文书
尊师重教主题班会
2015/08/14 职场文书