JavaScript进阶系列01,函数的声明,函数参数,函数闭包
本篇主要体验JavaScript函数的声明、函数参数以及函数闭包。
□ 函数的声明
※ 声明全局函数
通常这样声明函数:
function doSth() {alert("可以在任何时候调用我");}
通过这种方式声明的函数属于Window对象,可以在任何地方调用,即在doSth方法的之前和之后都可以调用。
可以在doSth方法之前调用:
doSth();function doSth() {alert("可以在任何时候调用我");}
可以在doSth方法之后调用:
function doSth() {alert("可以在任何时候调用我");}doSth();
※ 把函数赋值给变量
var doSomething = function() {alert("只能在声明我之后再调用");};
不可以在doSomething方法之前调用:
doSomething();var doSomething = function() {alert("只能在声明我之后再调用");};
以上,报"undefined funciton ..."错。
可以在doSomething方法之后调用:
var doSomething = function() {alert("只能在声明我之后再调用");};doSomething();
□ 函数参数
※ 即使声明的函数没有参数,也可以在调用时传入参数
doSth("你好");function doSth() {alert(arguments[0]);}
输出结果:你好
※ arguments.callee属性表示函数引用
doSth("你好");function doSth() {alert(arguments.callee);}

以上,在函数内部使用arguments.callee属性表示的是函数本身。
※ arguments.callee()方法递归调用函数
doSth();function doSth() {alert("你好");arguments.callee();}
输出结果:不断显示"你好"
□ 函数闭包
※ 闭包的形成
先看下面代码:
function doSth(val) {return function() {alert(val);};}var fn = doSth("hello");fn();
输出结果:hello
在doSth方法内部返回一个匿名函数,通过fn()执行匿名函数,把doSth方法的参数变量val打印了出来。在这里,doSth方法内部的匿名函数被称作"闭包"。换句话说,我们在内存上创建了一个匿名对象。
※ 闭包的释放
如果在调用fn方法之后,通过fn=null,把fn设置为null,首先匿名函数所占内存被释放,接着,由于变量val不再被引用,val所占内存被释放,最后释放doSth所占内存。
※ 过多的"闭包"会增加内存开销
function doSth(val) {return function() {alert(val);};}var fn = doSth("hello");var fn2 = doSth("hello2");fn();fn2();fn();
输出结果:依次显示hello, hello2, hello
无论是调用fn方法,还是fn2方法,都会在内存上创建匿名对象,消耗更多的内存。
※ 使用"闭包"创建module
举例:声明一个函数用来创建唯一的ID
var i = 0;function CreateUniqueName() {var name = "name" + i;i = i + 1;return name;}var name1 = CreateUniqueName();var name2 = CreateUniqueName();alert(name1 + " " + name2);
输出结果:name0 name1
以上存在几个问题:
1、创建的函数不是全局的,只能在当前页使用
2、变量i和方法CreateUnqiueName都是全局的,这可能会造成与第三方代码的名称冲突
所以,我们应该把以上的逻辑写成全局,并做成一个module,并自定义名称。
var myUtilty = (function() {var i = 0;return {CreateUniqueName: function() {var name = "name" + i;i = i + 1;return name;}};}());var name1 = myUtilty.CreateUniqueName();var name2 = myUtilty.CreateUniqueName();alert(name1 + " " + name2);
○ (function(){}());被称作是匿名、自触发函数,返回一个json对象,并且只执行一次
○ 正因为匿名、自触发函数只被执行一次,所有全局只有一个myUtitly对象,不会过多消耗内存
○ json对象的键CreateUniqueName对应一个匿名方法
○ 匿名、自触发函数可以被看作是全局的、唯一的"闭包"
“JavaScript进阶系列”包括:
JavaScript进阶系列01,函数的声明,函数参数,函数闭包
JavaScript进阶系列02,函数作为参数以及在数组中的应用
JavaScript进阶系列03,通过硬编码、工厂模式、构造函数创建JavaScript对象
JavaScript进阶系列04,函数参数个数不确定情况下的解决方案
JavaScript进阶系列05,事件的执行时机, 使用addEventListener为元素同时注册多个事件,事件参数
JavaScript进阶系列06,事件委托
JavaScript进阶系列07,鼠标事件
JavaScript进阶系列01,函数的声明,函数参数,函数闭包的更多相关文章
- JavaScript进阶系列04,函数参数个数不确定情况下的解决方案
本篇主要体验函数参数个数不确定情况下的一个解决方案.先来看一段使用函数作为参数进行计算的实例. var calculate = function(x, y, fn) { return fn(x, y) ...
- JavaScript进阶系列02,函数作为参数以及在数组中的应用
有时候,把函数作为参数可以让代码更简洁. var calculator = { calculate: function(x, y, fn) { return fn(x, y); } }; var su ...
- JavaScript进阶系列07,鼠标事件
鼠标事件有Keydown, Keyup, Keypress,但Keypress与Keydown和Keyup不同,如果按ctrl, shift, caps lock......等修饰键,不会触发Keyp ...
- JavaScript进阶系列06,事件委托
在"JavaScript进阶系列05,事件的执行时机, 使用addEventListener为元素同时注册多个事件,事件参数"中已经有了一个跨浏览器的事件处理机制.现在需要使用这个 ...
- JavaScript进阶系列05,事件的执行时机, 使用addEventListener为元素同时注册多个事件,事件参数
本篇体验JavaScript事件的基本面,包括: ■ 事件必须在页面元素加载之后起效■ 点击事件的一个简单例子■ 为元素注册多个点击事件■ 获取事件参数 ■ 跨浏览器事件处理 □ 事件必须在页面元素加 ...
- JavaScript进阶系列03,通过硬编码、工厂模式、构造函数创建JavaScript对象
本篇体验通过硬编码.工厂模式.构造函数来创建JavaScript对象. □ 通过硬编码创建JavaScript对象 当需要创建一个JavaScript对象时,我们可能这样写: var person = ...
- 深入理解javascript作用域系列第三篇——声明提升(hoisting)
× 目录 [1]变量 [2]函数 [3]优先 前面的话 一般认为,javascript代码在执行时是由上到下一行一行执行的.但实际上这并不完全正确,主要是因为声明提升的存在.本文是深入理解javasc ...
- JavaScript学习系列博客_18_JavaScript中的匿名函数
匿名函数 - 用函数声明的方式创建一个函数时,不加函数名称. function sum(){ console.log("我是函数sum")} - 不加名称,这样写浏览器是会报错的. ...
- javascript进阶系列专题:作用域与作用域链
字面意思,作用域是指变量和函数的作用范围,换言之,作用域决定了变量和函数的可见性和有效时间.javascript作用域是用函数来区分,与其他语言的大括号不同. for (var i=0; i<5 ...
随机推荐
- vim助手
移动光标 hjkl 2w 向前移动两个单词 3e 向前移动到第 3 个单词的末尾 0 移动到行首 $ 当前行的末尾 gg 文件第一行 G 文件最后一行 行号+G 指定行 <ctrl>+o ...
- 高可用的MongoDB集群【转】
刚接触MongoDB,就要用到它的集群,只能硬着头皮短时间去看文档和尝试自行搭建.迁移历史数据更是让人恼火,近100G的数据文件,导入.清理垃圾数据执行的速度蜗牛一样的慢.趁着这个时间,把这几天关于M ...
- 2010 NEERC Western subregional
2010 NEERC Western subregional Problem A. Area and Circumference 题目描述:给定平面上的\(n\)个矩形,求出面积与周长比的最大值. s ...
- Android 7.0 新增功能和api
Android 7.0 Nougat 为用户和开发者引入多种新功能.本文重点介绍面向开发者的新功能. 请务必查阅 Android 7.0 行为变更以了解平台变更可能影响您的应用的领域. 要详细了解 A ...
- andriod 自定义来电界面功能
由于近期所做一个项目需要做类似于“来电秀”的功能,所以上网搜索了一些相关资料,加上自己的一些想法,做了一个Demo.一下是我对该功能实现的一些想法,不对的地方欢迎各位指出.最后我会给出Demo 的源代 ...
- C#用Oracle.DataAccess中连接Oracle要注意版本问题!
客户端Oracle.DataAccess.dll与服务器版本不一致时,如下修改:1.在客户端Web.config中,增加如下配置:<runtime> <assemblyBinding ...
- 洛谷P3387 【模板】缩点 题解
背景 今天\(loj\)挂了,于是就有了闲情雅致来刷\(luogu\) 题面 洛谷P3387 [模板]缩点传送门 题意 给定一个\(n\)个点\(m\)条边有向图,每个点有一个权值,求一条路径,使路径 ...
- 使用Golang编写优化算法 (1)
动手写点东西是学习新知识很重要的一个阶段.之前用 Python 和 JavaScript 实现优化算法,现在用 Golang 来实现.语法上略有不爽,某些C语言的思维又回来了. - Golang 用 ...
- IntelIJ IDEA配置Tomcat遇到问题Error during artifact deployment. See server log for details
IntelIJ IDEA在配置tomcat的时候会遇到Error during artifact deployment. See server log for details.这样的问题,我的系统是W ...
- Action的模型绑定
- 你真的会用Action的模型绑定吗? 在QQ群或者一些程序的交流平台,经常会有人问:我怎么传一个数组在Action中接收.我传的数组为什么Action的model中接收不到.或者我在ajax的 ...