理解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控制iframe滚动的代码
Apr 10 Javascript
javascript fullscreen全屏实现代码
Apr 09 Javascript
yepnope.js 异步加载资源文件
Sep 08 Javascript
Jquery创建一个层当鼠标移动到层上面不消失效果
Dec 12 Javascript
JS设置获取cookies的方法
Jan 26 Javascript
javascript面向对象之共享成员属性与方法及prototype关键字用法
Jan 13 Javascript
深入讲解AngularJS中的自定义指令的使用
Jun 18 Javascript
JavaScript模板引擎Template.js使用详解
Dec 15 Javascript
一个简易时钟效果js实现代码
Mar 25 Javascript
vue 实现 ios 原生picker 效果及实现思路解析
Dec 06 Javascript
Django+Vue实现WebSocket连接的示例代码
May 28 Javascript
vue2 拖动排序 vuedraggable组件的实现
Aug 08 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+Html+缓存
2006/11/25 PHP
基于php伪静态的实现详细介绍
2013/04/28 PHP
PHP 快速排序算法详解
2014/11/10 PHP
PHP5.2下preg_replace函数的问题
2015/05/08 PHP
Laravel find in set排序实例
2019/10/09 PHP
基于jQuery的模仿新浪微博时间的组件
2011/10/04 Javascript
js获取单选框或复选框值及操作
2012/12/18 Javascript
基于jquery实现的图片在各种分辨率下未知的容器内上下左右居中
2014/05/11 Javascript
再谈javascript注入 黑客必备!
2016/09/14 Javascript
js+canvas实现动态吃豆人效果
2017/03/22 Javascript
angular+webpack2实战例子
2017/05/23 Javascript
javaScript之split与join的区别(详解)
2017/11/08 Javascript
微信小程序实现左右联动的实战记录
2018/07/05 Javascript
Vue配合iView实现省市二级联动的示例代码
2018/07/27 Javascript
用node开发并发布一个cli工具的方法步骤
2019/01/03 Javascript
微信小程序语音同步智能识别的实现案例代码解析
2020/05/29 Javascript
如何用JS模拟实现数组的map方法
2020/07/30 Javascript
ReactRouter的实现方法
2021/01/25 Javascript
Linux中Python 环境软件包安装步骤
2016/03/31 Python
Django中redis的使用方法(包括安装、配置、启动)
2018/02/21 Python
修复 Django migration 时遇到的问题解决
2018/06/14 Python
Python Django给admin添加Action的方法实例详解
2019/04/29 Python
Python OpenCV 使用滑动条来调整函数参数的方法
2019/07/08 Python
在PyCharm的 Terminal(终端)切换Python版本的方法
2019/08/02 Python
Python3 sys.argv[ ]用法详解
2019/10/24 Python
HTML5 语义化结构化规范化
2008/10/17 HTML / CSS
详解HTML5中download属性的应用
2015/08/06 HTML / CSS
解析html5 canvas实现背景鼠标连线动态效果代码
2019/06/17 HTML / CSS
请解释virtual关键字的含义
2015/06/17 面试题
幼师专业求职推荐信
2013/11/08 职场文书
2014年宣传部工作总结
2014/11/12 职场文书
学雷锋倡议书
2015/01/19 职场文书
小学公民道德宣传日活动总结
2015/03/23 职场文书
工地食品安全责任书
2015/05/09 职场文书
2015党建工作简报
2015/07/21 职场文书
ThinkPHP5和ThinkPHP6的区别
2021/03/31 PHP