理解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打字小游戏代码
Dec 26 Javascript
一个页面元素appendchild追加到另一个页面元素的问题
Jan 27 Javascript
将json当数据库一样操作的javascript lib
Oct 28 Javascript
JavaScript代码复用模式详解
Nov 07 Javascript
浅谈jquery的map()和each()方法
Jun 12 Javascript
Vue报错:Uncaught TypeError: Cannot assign to read only property’exports‘ of object’#‘的解决方法
Jun 17 Javascript
js自定义弹框插件的封装
Aug 24 Javascript
AngularJS双向数据绑定原理之$watch、$apply和$digest的应用
Jan 30 Javascript
详解React项目的服务端渲染改造(koa2+webpack3.11)
Mar 19 Javascript
vue-vuex中使用commit提交mutation来修改state的方法详解
Sep 16 Javascript
详解webpack编译速度提升之DllPlugin
Feb 05 Javascript
详解Vue3.0 + TypeScript + Vite初体验
Feb 22 Vue.js
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截取后台登陆密码的代码
2012/05/05 PHP
php中判断文件存在是用file_exists还是is_file的整理
2012/09/12 PHP
PHP实现微信网页授权开发教程
2016/01/19 PHP
IE JS无提示关闭窗口不提示的方法
2010/04/29 Javascript
基于JQuery的一个简单的鼠标跟随提示效果
2010/09/23 Javascript
js jquery验证银行卡号信息正则学习
2013/01/21 Javascript
jq选项卡鼠标延迟的插件实例
2013/05/13 Javascript
javascript显示用户停留时间的简单实例
2013/08/05 Javascript
使用Curl命令查看请求响应时间方法
2016/11/04 Javascript
Bootstrap基本模板的使用和理解1
2016/12/14 Javascript
javascript 单例模式详解及简单实例
2017/02/14 Javascript
NodeJs测试框架Mocha的安装与使用
2017/03/28 NodeJs
使用vue框架 Ajax获取数据列表并用BootStrap显示出来
2017/04/24 Javascript
Bootstrap提示框效果的实例代码
2017/07/12 Javascript
使用webpack构建应用的方法步骤
2019/03/04 Javascript
JavaScript canvas实现跟随鼠标事件
2020/02/10 Javascript
tensorflow输出权重值和偏差的方法
2018/02/10 Python
Python面向对象之继承和组合用法实例分析
2018/08/27 Python
Selenium+Python 自动化操控登录界面实例(有简单验证码图片校验)
2019/06/28 Python
Python之pymysql的使用小结
2019/07/01 Python
基于FME使用Python过程图解
2020/05/13 Python
python使用多线程+socket实现端口扫描
2020/05/28 Python
pycharm专业版远程登录服务器的详细教程
2020/09/15 Python
西尔斯百货官网:Sears
2016/09/06 全球购物
财务方面个人工作的自我评价
2013/12/28 职场文书
绿化先进工作者事迹材料
2014/01/30 职场文书
大学军训感言400字
2014/03/11 职场文书
校庆活动策划方案
2014/06/05 职场文书
2015年幼儿园新年寄语
2014/12/08 职场文书
辞职信标准格式
2015/02/27 职场文书
2015年项目经理工作总结
2015/04/30 职场文书
旗帜观后感
2015/06/08 职场文书
中秋联欢会主持词
2015/07/04 职场文书
2016抗战胜利71周年红领巾广播稿
2015/12/18 职场文书
canvas绘制折线路径动画实现
2021/05/12 Javascript
MySQL命令无法输入中文问题的解决方式
2021/08/30 MySQL