理解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编程起步(第三课)
Feb 27 Javascript
基于Jquery的简单&简陋Tabs插件代码
Feb 09 Javascript
兼容主流浏览器的jQuery+CSS 实现遮罩层的简单代码
Oct 14 Javascript
javascript中Date对象的getDay方法使用指南
Dec 22 Javascript
JavaScript判断undefined类型的正确方法
Jun 30 Javascript
jQuery检测滚动条是否到达底部
Dec 15 Javascript
浅谈jQuery 选择器和dom操作
Jun 07 Javascript
javascript中href和replace的比较(详解)
Nov 25 Javascript
Vuejs实现购物车功能
Nov 05 Javascript
详解js正则表达式验证时间格式xxxx-xx-xx形式
Feb 09 Javascript
Vue实现开心消消乐游戏算法
Oct 22 Javascript
vue2.x数组劫持原理的实现
Apr 19 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中修改浏览器的User-Agent来伪装你的浏览器和操作系统
2011/07/29 PHP
php jq jquery getJSON跨域提交数据完整版
2013/09/13 PHP
PHP读取文件内容的五种方式
2015/12/28 PHP
thinkPHP自动验证机制详解
2016/12/05 PHP
DOM相关内容速查手册
2007/02/07 Javascript
Extjs学习过程中新手容易碰到的低级错误积累
2010/02/11 Javascript
js 兼容多浏览器的回车和鼠标焦点事件代码(IE6/7/8,firefox,chrome)
2010/04/14 Javascript
js使用for循环与innerHTML获取选中tr下td值
2014/09/26 Javascript
JavaScript从数组中删除指定值元素的方法
2015/03/18 Javascript
JavaScript模拟实现继承的方法
2015/03/30 Javascript
javascript实现树形菜单的方法
2015/07/17 Javascript
浅谈angularJS中的事件
2016/07/12 Javascript
AngularJS基础 ng-keypress 指令简单示例
2016/08/02 Javascript
三种方式实现瀑布流布局
2017/02/10 Javascript
jQuery - AJAX load() 实例用法详解
2019/08/27 jQuery
flexible.js实现移动端rem适配方案
2020/04/07 Javascript
vue中实现拖动调整左右两侧div的宽度的示例代码
2020/07/22 Javascript
vue实现移动端拖动排序
2020/08/21 Javascript
[01:10]DOTA2次级职业联赛 - Fly战队宣传片
2014/12/01 DOTA
[01:41]DOTA2 2015国际邀请赛中国区预选赛第三日战报
2015/05/28 DOTA
Python模拟百度登录实例详解
2016/01/20 Python
分享6个隐藏的python功能
2017/12/07 Python
Python中flatten( )函数及函数用法详解
2018/11/02 Python
Python3.4学习笔记之常用操作符,条件分支和循环用法示例
2019/03/01 Python
在 Linux/Mac 下为Python函数添加超时时间的方法
2020/02/20 Python
python matplotlib模块基本图形绘制方法小结【直线,曲线,直方图,饼图等】
2020/04/26 Python
python Scrapy爬虫框架的使用
2021/01/21 Python
使用CSS3编写灰阶滤镜来制作黑白照片效果的方法
2016/05/09 HTML / CSS
应届专科生个人的自我评价
2014/01/05 职场文书
社区义诊活动总结
2014/04/30 职场文书
三提三创主题教育活动查摆整改措施
2014/10/25 职场文书
2015仓库保管员年终工作总结
2015/05/13 职场文书
感谢师恩主题班会
2015/08/17 职场文书
vue数据字典取键值项目的字典问题
2022/04/12 Vue.js
spring 项目实现限流方法示例
2022/07/15 Java/Android
Linux中一对多配置日志服务器的详细步骤
2022/07/23 Servers