1、函数介绍
函数在JavaScript中能够通过单一的调用而执行一组操作。在JavaScript中,函数(function)有几种不同的称谓,分别是:函数、方法和构造器,定义一个函数为某一个对象的属性,则称这个函数为方法,构造器则是函数与new操作符一起操作的函数。有以下几种定义函数的方式:
function maximum(x,y){
if(x > y)
return x;
else
return y;
}
maximum(5,6) //Returns 6;
这种定义的方式在定义顶层函数时非常常用。
var obj = new Object();
obj.maximum = function (x,y) {
if(x > y)
return x;
else
return y;
};
obj.maximum(5,6) //Returns 6;
这种定义方式在定义函数作为一个对象的方法时最常用。
var maximum = new Function ("x","y","if(x > y) return x; else return y;");
maximum(5,6); //Returns 6;
这种定义方式不常用。
2、函数定义
函数定义指的是:在JavaScript引擎内定义一个函数对象。对于一个顶层函数,会把这个对象作为一个属性增加到全局对象中;对于一个内嵌的函数(定义在函数内的函数),则会把这个对象加到激活对象
(activation object)
中。顶层函数会在执行这个脚本之前定义,也就是说,在执行脚本之前,会为这个顶层函数创建函数对象,并加入到全局对象中。看下面的例子,一旦JavaScript解释器解析完毕开始执行下面的语句时,会为‘func’创建函数对象并作为一个属性加入到全局对象中:
/*函数'func'在这里可以被调用,因为func的定义在脚本开始执行时已经发生.*/
alert(func(2)); //Returns 8
//这个语句覆盖了func的值为true.
var func = true;
alert(func); //prints true;
/*当脚本开始执行的时候,解析下面的语句并且会为函数‘func’定义函数对象。*/
function func(x){
return x * x * x;
}
而对于一个内嵌的函数,则函数定义过程发生在当调用外部函数的时候,会定义内嵌的函数,并为这个内嵌函数创建函数对象,加入到外部函数的激活对象(activation object)中。例如:
function outerFn()
{
function innerFn()
{
}
}
outerFn(); //调用 outerFn 会引起innerFn的定义当outerFn 函数体开始执行的时候
注意
:对于函数构造器来说,函数定义会发生在调用‘Function’构造器的时间。
3、范围链
范围链指的是一个对象链,当在对象链中查找一个变量的时候,对象链的对象的属性能够被查找
。在JavaScript中,函数在定义之后就会有他们的范围链,这个范围链是在他们执行的时候的范围链,而不是在他们调用的时候的范围链
(
It is this scope chain in which they execute rather than the scope chain from which they are invoked.
)
,比如:
function outerFn(i){
return function innerFn(){
return i;
}
}
var innerFn = outerFn(4);
innerFn();//Returns 4
在掉用innerFn的时候,变量i并没有在innerFn内部定义,也没有在全局对象中定义,但是这句话是可以执行的,返回值为4,那么这个i是从哪来的呢?下面从顶层函数来慢慢分析:
3.1 全局函数
顶层函数的执行范围链是非常直接的:
var x = 10;
var y = 0;
function testFn(i){
var x = true;
y = y + 1;
alert(i);
}
testFn(10);
-
Global Object:在JavaScript引擎开始执行代码的时候,会创建一个全局对象,并初始化全局对象一些预定义的值,像
‘Infinity’, ‘Math’等。脚本中的全局变量只是定义在这个全局对象中的属性,像上面代码中的x呵y变量。
-
Activation Object:当JavaScript引擎调用任何的函数的时候,它会创建一个新的对象,也就是Activation Object激活对象,然后将在函数内部定义的变量以及通过arguments传递进来的参数都会被定义到这个激活对象中。然后将这个对象加入到执行范围链的前端。
3.2 内嵌函数
对于内嵌函数,范围链的形成比较复杂,看下面的例子:
function outerFn(i,j)
{
var x = i + j;
return function innerFn(x)
{
return i + x;
}
}
var func1 = outerFn(5,6);
var func2 = outerFn(10,20);
alert(func1(10));//Returns 15
alert(func2(10));//Returns 20
能够看到,在分别调用func1(10)和func2(10)的时候,变量i具有不同的值,下面一步步分析:
在下面的语句执行的时候
var func1 = outerFn(5,6);
会发生三个个动作,一是创建outerFn函数的激活对象(Activation Object);然后定义innerFn函数,并且作为outerFn的激活对象的一个属性加入到
outerFn的激活对象中;因为每个函数在定义的时候都会有它自己的范围链,并且这个范围链是执行范围链,这个时候的执行范围链包含outerFn的激活对象以及全局对象。然后会把这个执行范围链为内嵌函数innerFn保存起来。执行完毕后,返回内嵌对象,并用func1来引用。
当执行这条语句时:
alert(func1(10));//Returns 15
创建func1的激活对象,并且加入到已经保存的执行范围链的最前端,就是在这个执行范围链下,func1开始执行。这样在这个范围链下,i属性就解决了。看下图,能表现的更清楚,对于func1的调用时候的范围链,如图所示:
对于func2的执行范围链,看下图:
从这两个图就能很清晰的看出来在func1呵func2两个方法调用的时候,i的值是不一样的。
4 激活对象与范围链
是不是在函数调用的时候,创建这个函数的激活对象,然后在函数执行完毕之后,这个激活对象就会被销毁呢?为了解答这个问题,下面根据例子来说明一下激活对象与范围链的关系。
4.1 没有内嵌函数的情况
看下面的例子:
function outerFn(x){
return x*x;
}
var y = outerFn(2);
没有内嵌函数,在调用函数时,会创建这个函数的激活对象,并把这个激活对象加入到执行范围链的最前端,需要注意的是,范围链是
唯一持有
这个激活对象的对象。当函数执行完毕之后,就把这个激活对象从执行范围链中删除,由于没有别的对象再引用这个激活对象了,因此这个激活对象会被垃圾回收器回收。
4.2 有内嵌函数,但是内嵌函数没有被其包围函数之外的对象引用
function outerFn(x)
{
//No reference for 'square' outside 'outerFn'
function square(x)
{
return x*x;
}
//No reference for 'cube' outside 'outerFn'
function cube(x)
{
return x*x*x;
}
var temp = square(x);
return temp/2;
}
var y = outerFn(5);
在一个函数有内嵌函数,并且内嵌函数没有被其外围函数之外的对象引用的时候,当调用外围函数时,这个函数的激活对象被创建,并将其加入到执行范围链的最前端,并且同样会被起内嵌函数的已保存范围链引用(在外围函数调用时,内嵌函数开始定义,内嵌函数定义的时候,会为其创建范围链),当这个外围函数退出的时候,它的激活对象从执行范围链中被删除。由于外围函数的激活对象和其内嵌对象是相互引用的,并且这两个对象都没有被外部的对象所引用,因此会被垃圾回收器回收。
4.3 内嵌函数被包围函数的外部对象引用
// 例子1
function outerFn(x)
{
//Inner function referenced outside through return
//value of 'outerFn'
return function innerFn()
{
return x*x;
}
}
//Reference to inner function returned.
var square = outerFn(5);
square();
例子2
var square;
function outerFn(x)
{
//Inner function referenced outside through global variable
//'square'
square = function innerFn()
{
return x*x;
}
}
outerFn(5);
square();
在具有内嵌函数,并且内嵌函数被外围对象引用的时候,当执行这个外部函数时,这个外部函数的激活对象被创建,并且把激活对象加入到执行范围链的最前端,同时,这个对象被内嵌函数的已保存的范围链所引用(在内嵌函数定义的时候会保存一个范围链)。当外部函数退出,这个激活对象会从执行范围链中被删除,但是它仍然在内嵌函数保存的范围链中有一个引用。由于有个外部的引用指向内嵌函数,因此这个激活对象一直保存在内嵌函数的已保存范围链中,并且在内嵌函数执行的时候可以被访问。
5 闭包和循环引用
这里讲一下由于闭包而引起的循环引用内存泄漏。闭包通常指的是内嵌的函数可以在其包围函数的外部调用,下面给出一个小例子:
function outerFn(x)
{
x.func = function innerFn()
{
}
}
var div = document.createElement("DIV");
outerFn(div);
通过这个例子我们能够观察到在DOM对象和JS对象之间的循环引用被创建。DOM对象div通过func属性指向内嵌的函数innerFn,而
内嵌的函数innerFn也有一个指向DOM对象div的引用x,这个x是保存在outerFn的激活对象中,并且这个激活对象被保存到内嵌函数的已保存范围链中。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
注意
:这篇文章翻译自MSDN的一篇文章,自己做了些加工与说明。可以点击这里
查看原文
- 大小: 14.1 KB
- 大小: 37.9 KB
- 大小: 38.6 KB
分享到:
相关推荐
高分设计源码,详情请查看资源内容中使用说明 高分设计源码,详情请查看资源内容中使用说明高分设计源码,详情请查看资源内容中使用说明高分设计源码,详情请查看资源内容中使用说明高分设计源码,详情请查看资源内容中使用说明高分设计源码,详情请查看资源内容中使用说明高分设计源码,详情请查看资源内容中使用说明高分设计源码,详情请查看资源内容中使用说明高分设计源码,详情请查看资源内容中使用说明高分设计源码,详情请查看资源内容中使用说明高分设计源码,详情请查看资源内容中使用说明高分设计源码,详情请查看资源内容中使用说明高分设计源码,详情请查看资源内容中使用说明高分设计源码,详情请查看资源内容中使用说明高分设计源码,详情请查看资源内容中使用说明高分设计源码,详情请查看资源内容中使用说明高分设计源码,详情请查看资源内容中使用说明高分设计源码,详情请查看资源内容中使用说明高分设计源码,详情请查看资源内容中使用说明高分设计源码,详情请查看资源内容中使用说明高分设计源码,详情请查看资源内容中使用说明高分设计源码,详情请查看资源内容中使用说明
SpringBoot2.0快速开发框架权限.rarSpringBoot2.0快速开发框架权限.rarSpringBoot2.0快速开发框架权限.rar
详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;
基于Qt开发的汽车车机系统上位机 & 常见类型汽车传感器信号模拟发生器 任务和要求: 任务: 根据发动机测控系统信号需求,设计一套发动机信号模拟器人机交互系统,能够根据需要向下位机输出控制信号,使其输出发动机测控系统需要的传感器模拟信号,给发动机测控系统的开发提供方便。 要求: 1.设计应包含上位机与下位机的交互程序及人机交互界面的设计,与下位机设计相结合,使其能够实现全部类型发动机传感器信号的模拟输出及显示。 2.设计中需要采用模块化开发程序。 3.所设计的人机交互界面简洁合理。 4.应考虑所设计系统的实用性。 具体工作内容: 1.根据设计目标,查阅相关设计标准和设计方法资料,对发动机信号模拟器设计中的关键工程原理和工程方法进行提炼,并围绕关键问题进行国内外设计现状调研,开展分析、评价与总结,确定主要研究内容,制定设计技术路线,制定设计计划(周进度),撰写开题报告,并进行开题答辩,开题报告参考文献应不少于15篇(其中外文文献不少于 4 篇,近五年文献不少于三分之一)。 2.根据设计要求和技术指标,进行满足功能原理需求的多方案拟定,考虑安全、 标准等多因素进行技术性与经济性评价
实验-三、数据库安全性(目的、要求和模板).doc
文件为第二天视频教程 在毕业设计的挑战中,有时我们需要以极短的时间完成一个相对复杂的项目,比如一个商城系统。虽然时间紧迫,但只要我们合理规划、高效执行,完全有可能在4天内完成一个基础且功能完备的商城系统。 商城系统,也被称为网上商城系统或Online Mall system,是一种功能完善的网上销售系统。该系统主要包括产品发布、在线订购、在线支付、在线客服等功能模块,旨在为企业或个人提供一个在线销售平台,实现商品的展示、交易和客户服务。 商城系统具有多种核心功能,如商品管理、订单管理、用户管理和营销管理。商品管理功能支持商品的添加、编辑、删除、分类和搜索,满足商家对商品信息的全面管理需求。订单管理功能则涵盖订单的生成、支付、发货、退款和评价等环节,确保交易流程的顺畅进行。用户管理功能包括用户的注册、登录、个人信息管理和收货地址管理等,提升用户体验。而营销管理功能则通过促销活动的设置、优惠券的发放和积分兑换等手段,帮助商家提升销售业绩。 商城系统的特点主要体现在功能性、易用性和安全性上。商城系统注重功能性的开发,每个功能都有其发挥作用的地方,满足商家的实际需求。
PPT模板,答辩PPT模板,毕业答辩,学术汇报,母校模板,我给母校送模板作品,周会汇报,开题答辩,教育主题模板下载。PPT素材下载。
小型餐饮管理系统-数据库设计报告.doc
本资源中的源码都是经过本地编译过可运行的,下载后按照文档配置好环境就可以运行。资源项目的难度比较适中,内容都是经过助教老师审定过的,应该能够满足学习、使用需求,如果有需要的话可以放心下载使用。有任何问题也可以随时私信博主,博主会第一时间给您解答!!! 本资源中的源码都是经过本地编译过可运行的,下载后按照文档配置好环境就可以运行。资源项目的难度比较适中,内容都是经过助教老师审定过的,应该能够满足学习、使用需求,如果有需要的话可以放心下载使用。有任何问题也可以随时私信博主,博主会第一时间给您解答!!! 本资源中的源码都是经过本地编译过可运行的,下载后按照文档配置好环境就可以运行。资源项目的难度比较适中,内容都是经过助教老师审定过的,应该能够满足学习、使用需求,如果有需要的话可以放心下载使用。有任何问题也可以随时私信博主,博主会第一时间给您解答!!
PPT模板,答辩PPT模板,毕业答辩,学术汇报,母校模板,我给母校送模板作品,周会汇报,开题答辩,教育主题模板下载。PPT素材下载。
2024年中国中空纤维膜行业研究报告
PPT模板,答辩PPT模板,毕业答辩,学术汇报,母校模板,我给母校送模板作品,周会汇报,开题答辩,教育主题模板下载。PPT素材下载。
实验三、数据库安全性实验报告.doc
PPT模板,答辩PPT模板,毕业答辩,学术汇报,母校模板,我给母校送模板作品,周会汇报,开题答辩,教育主题模板下载。PPT素材下载。
java电子相册源码.rarjava电子相册源码.rarjava电子相册源码.rarjava电子相册源码.rar
玉米脱粒机设计及其总装配图(论文、dwg图)
studyopencv2
2024-2030全球与中国牛肉卷饼市场现状及未来发展趋势
在KITTI车辆数据集,采用随机多尺度变化增强车辆训练集样本数量,采用k-means聚类获取最优先验候选框大小,引入到YOLOv3模型中,提升模型的车辆检测精度和鲁棒性。.zip
详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;