函数表达书-读书笔记

定义函数的方式有两种:一种是函数声明,另一种就是函数表达式。函数声明的语法如下:

function functionName(arg0,arg1,arg2){//函数体
}

函数声明,有一个重要特征就是函数声明提升。也就是在执行代码之前会先读取函数声明,也就意味着可以把函数声明放在调用它的语句后面。

sayHi();
function sayHi(){console.log("Hi!");
}

下面介绍函数表达式的语法:

var functionName = function(arg0,arg1,arg2){//函数体  
}

这种看起来好像常规的变量赋值语句,就是创建一个函数并将它赋值给变量functionName,这样的函数就是匿名函数,注意function关键字后面没有标识符,匿名函数的name属性是空字符串。

函数表达式和其他表达式一样,在使用之前必须先赋值。

sayHi(); //错误:函数还不存在
var sayHi = function(){alert("Hi!");
};

一、闭包

闭包是指有权访问另一个函数作用域中的变量的函数。创建闭包的常见方式,就是在一个函数内部创建另一个函数。栗如:

function createComparisonFunction(propertyName) {return function(object1, object2){var value1 = object1[propertyName];var value2 = object2[propertyName];if (value1 < value2){return -1;} else if (value1 > value2){return 1;} else {return 0;}};
}

在函数执行过程中,为读取和写入变量的值,需要在作用域链中查找变量,栗如:

function compare(value1, value2){if (value1 < value2){return -1;} else if (value1 > value2){return 1;} else {return 0;}
}
var result = compare(5, 10);

上面代码先定义了compare()函数,然后又在全局作用域调用了它,当调用compare()时,会创建一个包含arguments、value1、value2的活动对象。全局执行环境的变量对象在compare()执行环境的作用域链中则处于第二位,如图:

在另一个函数内部定义的函数会将包含函数(即外部函数)的活动对象添加到它的作用域链中。因此,在createComparisonFunction()函数内部定义的匿名函数的作用域链中,实际上将会包含外部函数createComparisonFunction()的活动对象。

var compare = createComparisonFunction("name");
var result = compare({ name: "Nicholas" }, { name: "Greg" });

在匿名函数从createComparisonFunction()中被返回后,它的作用域链被初始化为包含createComparisonFunction()函数的活动对象和全局变量对象。这样,匿名函数就可以访问在createComparisonFunction()中定义的所有变量。更为重要的是,createComparisonFunction()函数在执行完毕后,其活动对象也不会被销毁,因为匿名函数的作用域链仍然在引用这个活动对象。换句话说,当createComparisonFunction()函数返回后,其执行环境的作用域链会被销毁,但它的活动对象仍然会留在内存中;直到匿名函数被销毁后,createComparisonFunction()的活动对象才会被销毁。

//创建函数
var compareNames = createComparisonFunction("name");
//调用函数
var result = compareNames({ name: "Nicholas" }, { name: "Greg" });
//解除对匿名函数的引用(以便释放内存)
compareNames = null;

首先,创建的比较函数被保存在变量compareNames中,通过设置compareNames为null解除该函数的引用,就等于通知垃圾回收机制将其清除。匿名函数的作用域链被销毁,其他作用域(除了全局作用域)也都可以安全地销毁了。

作用域链带来了一个副作用,闭包只能取得包含函数中任何变量的最后一个值。闭包所保存的是整个变量对象,而不是某个特殊的变量。举栗:

function createFunctions(){var result = new Array();for (var i=0; i < 10; i++){result[i] = function(){return i;};}return result;
}

这个函数会返回一个函数数组,表面上看,似乎每个函数都有自己的索引值,即位置0的函数返回0,位置1的函数返回1,以此类推。但实际上,每个函数都返回10。因为每个函数的作用域链中凑保存着createFunctions()函数的活动对象,所以它们引用的都是同一个变量i。当createFunctions()函数返回后,变量i的值是10,此时每个函数都引用着保存变量i的同一个变量对象,所以在每个函数内部i的值都是10。

我们可以通过创建另一个匿名函数强制让闭包的行为符合预期。

function createFunctions(){var result = new Array();for (var i=0; i < 10; i++){result[i] = function(num){return function(){return num;};}(i);}return result;
}

重写了createFunctions()函数后,每个函数就会返回各自不同的索引值了。在这里,我们没有直接把闭包赋值给数组,而是定义了一个匿名函数,并立即执行该匿名函数的结果赋给数组。这里的匿名函数有一个参数num,也就是最终的函数要返回的值。

在调用每个匿名函数时,我们传入了变量i。由于函数参数是按值传递的,所以就会将变量i的当前值复制给参数num。而在这个匿名函数内部,又创建并返回一个访问num的闭包。这样一来,result数组中的每个函数都有自己num变量的一个副本,因此就可以参会各自不同的数值了。

 

参考资料

《javascript高级程序设计(第3版)》第7章 函数表达式

转载于:https://www.cnblogs.com/winteronlyme/p/6723234.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/396145.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vs2012新建项目产生的问题

当用vs新建web项目时遇到 只需下载一个vs2012的更新插件 http://download.microsoft.com/download/A/0/2/A02C37E0-77F7-448A-BD5C-F66AB1F78DBC/VS11-KB3002339.exe 点击安装更新即可. 转载于:https://www.cnblogs.com/GreenLeaves/p/5452073.html

zoj4062 Plants vs. Zombies 二分+模拟(贪心的思维)

题目传送门 题目大意&#xff1a;有n个植物排成一排&#xff0c;标号为1-n&#xff0c;每株植物有自己的生长速度ai&#xff0c;每对植物浇一次水&#xff0c;该株植物就长高ai&#xff0c;现在机器人从第0个格子出发&#xff0c;每次走一步&#xff0c;不能停留&#xff0c;每…

MyBatis注解模式批量insert方法

2019独角兽企业重金招聘Python工程师标准>>> 方法一:script标签方式 Insert("<script>insert into xxx (channelId,siteId) " "values " "<foreach collection\"list\" item\"item\" index\"index\&quo…

关于eclipse中文注释乱码的问题

今天打开了一个以前的android项目&#xff0c;发现中文注释都成乱码啦&#xff01;&#xff01;&#xff01; 后来在网上找了一会解决方法&#xff0c;知道了中文的编码大体是两种&#xff1a;GBK(汉字内码扩展规范)和UTF-8(8-bit Unicode Transformation Format)。 因此问题的…

python入门(5)使用文件编辑器编写代码并保存执行

python入门&#xff08;5&#xff09;使用文件编辑器编写代码并保存执行 两款文本编辑器&#xff1a; 一个是Sublime Text&#xff0c;免费使用&#xff0c;但是不付费会弹出提示框&#xff1a; 一个是Notepad&#xff0c;免费使用&#xff0c;有中文界面&#xff1a; 请注意&…

linux 批量同步,多主机目录到备份服务器批量同步脚本

为了方便同步多个主机的目录到备份服务器&#xff0c;写了如下脚本&#xff1a;#!/usr/bin/perluse strict;use File::Spec;use File::Basename;use File::Path;#设定存储路径my $storedir"/backup/";while(){chomp;my ($host,$s_path)split /\t/;my $project_namefi…

交流电的有效值rms值_交流电路的功率三角因数原来是这样理解的

点击“电工电气学习”关注即可免费订阅&#xff01;电工学习网&#xff1a;www.diangon.com关注电工学习网官方微信公众号“电工电气学习”&#xff0c;收获更多经验知识。交流电路中消耗的电能可以用直角三角形的三个边来表示&#xff0c;通常称为功率三角形我们在关于交流电路…

CSS3酷炫样式集合

1、30种炫酷CSS鼠标滑过按钮特效 2、CSS 变量实现炫酷鼠标悬浮效果 3、基于CSS3和jQuery实现跟随鼠标方位的Hover特效 4、css3金属质感登录表单 4、CSS3动态下拉菜单 5、CSS3鼠标悬浮特效 转载于:https://www.cnblogs.com/mankii/p/9922981.html

NOIP2008 普及组T4 立体图 解题报告-S.B.S.(施工未完成)

题目描述 小渊是个聪明的孩子&#xff0c;他经常会给周围的小朋友们将写自己认为有趣的内容。最近&#xff0c;他准备给小朋友们讲解立体图&#xff0c;请你帮他画出立体图。 小渊有一块面积为m*n的矩形区域&#xff0c;上面有m*n个边长为1的格子&#xff0c;每个格子上堆了一些…

HBase基础知识(三):HBase架构进阶、读写流程、MemStoreFlush、StoreFile Compaction、Region Split

1. 架构原理 1&#xff09;StoreFile 保存实际数据的物理文件&#xff0c;StoreFile以HFile的形式存储在HDFS上。每个Store会有一个或多个StoreFile&#xff08;HFile&#xff09;&#xff0c;数据在每个StoreFile中都是有序的。 2&#xff09;MemStore 写缓存&#xff0c;由于…

第一章节测试

大家在做第一章测试题时&#xff0c;需要复习如下相关知识点&#xff1a;编译型VS解释型、变量名规范、数据类型、程序交互、格式化输出、运算符、流程控制。1.简述编译型与解释型语言的区别&#xff0c;且分别列出你知道的那些语言属于编译型&#xff0c;哪些属于解释型。2.执…

VS2015升级Update2之后Cordova程序提示:此应用程序无法在此电脑上运行

VS2015在升级到Update2之后&#xff0c;有可能出现如下异常&#xff0c;在运行Cordova项目时提示&#xff1a; 查看输出面板会有乱码错误信息&#xff1a; 出现此问题的原因是在于npm程序损坏了。vs调用的npm程序并不是在node安装目录下的npm&#xff0c;而是在&#xff1a; C:…

双鉴探测器是哪两种探测方式结合_老师傅带你看懂火灾探测器的种类和基本原理,看完涨知识了...

为什么极早期的火灾探测十分关键&#xff1f;火灾的产生我们生活的环境中充满着大量的可燃物质&#xff0c;空气中的氧气含量通常也足够满足燃烧条件。但是还有另外一个形成火灾的条件就是&#xff1a;点火能量必须可以驱使氧化的过程开始。点火能量源可以是多种多样的&#xf…

分析不同类型页面渲染过程

现在让我们看看浏览器从网络上加载资源所耗费的时间&#xff08;我们忽略从缓存以及从CDN等中间商网络上加载资源&#xff09;&#xff0c;我们首先要知道的是&#xff1a; 一个到无服务的网路往返 (传播延迟) 大约100ms服务器对于HTML文档的响应大约100ms&#xff0c;对于其他…

ImageLoader加载图片

先导universal-image-loader-1.9.3包 在application配置 android:name".MyApplication" intent权限 1 package com.ch.day13_imageloaderdemo;2 3 import java.io.File;4 5 import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiscCache; 6 impor…

Access denied for user 'root'@'localhost' (using password: YES) 问题解决小记

初学php&#xff0c;按照视频安装后好mysql后 终端运行命令 mysql -u root -p 然后输入安装mysql时输入的密码六个1&#xff0c;会报这样的错误&#xff1a;Access denied for user rootlocalhost (using password: YES) &#xff1b; 百度了一大堆&#xff0c;大海捞针一般找…

创业者具备的五大技能_一、如今大学生创业需要具备哪些知识与技能?

我参加过两次互联网&#xff0b;大赛&#xff0c;分别获得过省赛的金奖与银奖&#xff0c;还曾参加山东省大大小小比赛26场&#xff0c;金奖累计获得12次。对当代创业的大学生所应具备哪些基本素质深有体会。&#xff08;1&#xff09;技能&#xff1a;1、自我认知及科学规划能…

BZOJ3387栅栏行动

首先&#xff0c;很容易想到Dp。设f[i][0]表示第i个栅栏走左边的最短路&#xff0c;f[i][1]表示第i个栅栏走右边的最短路。 所以&#xff0c;我们要找一个刚好在第i个栅栏的左右边界下面的栅栏。如图所示&#xff1a; 则有&#xff1a; f[i][0] min(f[k][0] |Left[i] - Left[…

小程序沉浸式_古北水镇红叶祭嵌入戏精学院 全新文旅沉浸模式让游客嗨起来...

2020年10月17日-24日&#xff0c;古北水镇第二届红叶祭火热来袭。今年除了“超级漫展二次元度假”的模式&#xff0c;古北水镇与顶级沉浸互动体验运营方——INX戏精学院合作&#xff0c;在深度体验空间的同时&#xff0c;加入了互动式的实景游戏体验&#xff0c;通过演员互动&a…

又拍云刘平阳,理性竞争下的技术品牌提升之道

云服务市场趋渐平稳&#xff0c;在这种情况下&#xff0c;就需要通过对某一项技术的深入应用来实现服务的精致化。同时&#xff0c;对品牌的打造和包装也必不可少。\\又拍云在2010年开始提供云服务&#xff0c;经过多年的发展&#xff0c;以及市场策略的转变&#xff0c;决定对…