理解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 相关文章推荐
jQuery的缓存机制浅析
Jun 07 Javascript
JavaScript中的原型链prototype介绍
Dec 30 Javascript
JS获得选取checkbox整行数据的方法
Jan 28 Javascript
jQuery判断元素是否显示 是否隐藏的简单实现代码
May 19 Javascript
jquery设置表单元素为不可用的简单代码
Jul 04 Javascript
JavaScript 轮播图和自定义滚动条配合鼠标滚轮分享代码贴
Oct 28 Javascript
浅谈JavaScript的闭包函数
Dec 08 Javascript
详解Next.js页面渲染的优化方案
Jan 27 Javascript
如何用原生js写一个弹窗消息提醒插件
May 24 Javascript
Element-ui DatePicker显示周数的方法示例
Jul 19 Javascript
JavaScript判断浏览器版本的方法
Nov 03 Javascript
vue点击自增和求和的实例代码
Nov 06 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调用三种数据库的方法(3)
2006/10/09 PHP
分页详解 从此分页无忧(PHP+mysql)
2007/11/23 PHP
php短域名转换为实际域名函数
2011/01/17 PHP
深入extjs与php参数交互的详解
2013/06/25 PHP
ecshop实现smtp发送邮件
2015/02/03 PHP
摘自织梦CMS的HTTP文件下载类
2015/08/08 PHP
详解WordPress中创建和添加过滤器的相关PHP函数
2015/12/29 PHP
PHP 中使用ajax时一些常见错误总结整理
2017/02/27 PHP
php实现session共享的实例方法
2019/09/19 PHP
Laravel框架使用技巧之使用url()全局函数返回前一个页面的地址方法详解
2020/04/06 PHP
IE 下Enter提交表单存在重复提交问题的解决方法
2014/05/04 Javascript
JavaScript中window.showModalDialog()用法详解
2014/12/18 Javascript
jQuery中eq()方法用法实例
2015/01/05 Javascript
JS简单实现tab切换效果的多窗口显示功能
2016/09/07 Javascript
打造自己的jQuery插件入门教程
2016/09/23 Javascript
jQuery模拟下拉框选择对应菜单的内容
2017/03/07 Javascript
SVG动画vivus.js库使用小结(实例代码)
2017/09/14 Javascript
基于vue 开发中出现警告问题去除方法
2018/01/25 Javascript
小程序图片长按识别功能的实现方法
2018/08/30 Javascript
详解Vue CLI3 多页应用实践和源码设计
2018/08/30 Javascript
微信小程序实现的图片保存功能示例
2019/04/24 Javascript
JS实现单张或多张图片持续无缝滚动的示例代码
2020/05/10 Javascript
vue如何在项目中调用腾讯云的滑动验证码
2020/07/15 Javascript
原生JS实现音乐播放器
2021/01/26 Javascript
python抓取网页内容示例分享
2014/02/24 Python
使用Python构建Hopfield网络的教程
2015/04/14 Python
numpy.meshgrid()理解(小结)
2019/08/01 Python
python 普通克里金(Kriging)法的实现
2019/12/19 Python
浅析Python 抽象工厂模式的优缺点
2020/07/13 Python
基于Python爬取股票数据过程详解
2020/10/21 Python
2014年大学生四年规划书范文
2014/04/03 职场文书
幼儿园师德演讲稿
2014/05/06 职场文书
幼儿园家长安全责任书
2014/07/22 职场文书
纪念九一八事变演讲稿1000字
2014/09/14 职场文书
MySQL中InnoDB存储引擎的锁的基本使用教程
2021/05/26 MySQL
浅谈如何提高PHP代码的质量
2021/05/28 PHP