javaScript函数与闭包
js中函数也是对象,具有一切对象的特征,可以作为表达式给变量赋值,可以作为函数的形参,或者函数的返回值,函数内可以嵌套函数等等,函数内以声明方式定义的函数是局部函数,用表达式声明的函数则由赋值变量的性质决定是局部还是全局的。函数内部使用var定义的局部变量只能在函数内部进行访问,在函数调用完成后被释放,从这点,可以模拟私有变量,块状作用域等。
1.javaScript函数定义
js中函数定义有两种方法:函数声明和函数表达式,函数声明可以进行函数声明提升,函数表达式则不会。
2.闭包
闭包是指有权访问另一个函数作用域中的变量的函数,和匿名函数是不同的概念。只不过其常见的创建方式,就是在一个函数内部创建另外一个函数。
对于一个闭包来说,其作用域链按照搜索顺序包括:闭包的活动对象——>闭包所在函数的活动对象——>全局活动对象。作用链上所有的活动对象,都能够在闭包内访问到。
关于闭包,需要注意以下几点:
1)闭包只能包含外部函数中任何变量的最后一个值,如下所示:
function createFunctions(){
var result=new Array();
;i<;i++){
result[i]=function(){
return i;
}
}
return result;
}
var result=createFunctions();
alert(result[]());
此时的返回值是10,而非想要的0.可以通过创建另一个匿名函数让闭包的行为符合预期。
function createFunctions(){
var result=new Array();
;i<;i++){
result[i]=(function(num){
return function(){
return num;
}
})(i);
}
return result;
}
var result=createFunctions();
alert(result[]());
经过上述重写后,函数能够返回各自不同的索引值。此时,没有把闭包直接赋值给数组,而是定义了一个匿名函数,并将该匿名函数调用的结果幅值给数组。
2)匿名函数的执行环境具有全局性,因此this对象通常指向window。每个函数在调用时候都会自动取得两个特殊变量:this和arguments;因为变量的搜索从闭包内部的活动对象开始,因此永远不可能直接访问到外部函数中的这两个变量,如果需要访问,需要将外部作用域中的this/arguments保存在一个闭包能够访问的变量中。
3)利用闭包可以模拟块状作用域
javascript没有块状作用域,只有函数级作用域和全局作用域,但可以使用匿名函数来模拟块状作用域。
(function(){
//这里是块状作用域
})();
如:
(function(){
; i >= ; i--) {
alert(i);
}
})();
在很多人参与开发的大型项目中,这种技术通常在全局作用域中被用在函数外部,从而限制向全局作用域添加过多的变量和函数。
4)由于闭包会包含其他函数的作用域,因此会比其他函数占用更多的内存,因此,除非必要,否则尽量不要使用闭包。
3.私有变量
私有变量:javascript任何函数中定义的局部变量,内部内部定义的其他函数,函数参数都是无法从外部访问的,因此被称为私有变量。
特权方法:能够访问私有变量和私有函数的公有方法称为特权方法。在函数内部创建闭包,那么闭包可以通过自己的作用域链访问外部函数的私有变量,利用这一点,可以创建特权方法。
特权方法一般有两种模式:
1)在构造函数中定义特权方法,将函数表达式赋值给this对象的属性。其问题是不能实现函数的复用。基本模式如下:
function Person(){
var name="bobo";
function privateMethod(){
return false;
}
this.publicMethod=function(){
alert(name);
return privateMethod;
}
}
var person1=new Person();
person1.publicMethod();
2)在私有域定义特权方法:在私有作用域中,首先定义私有变量和私有函数,之后用表达式的形式定义构造函数和公有方法,构造函数赋予的变量不能使用var修饰,因此可以在私有域外面访问到,公有方法在构造函数对应的原型中定义。
(function(){
var name="bobo";
//没有使用var关键字,因此Person对象是一个全局变量,可以在私有作用域之外访问到
Person=function(value){
name=value;
};
Person.prototype.setName=function(newValue){
name=newValue;
};
Person.prototype.getName=function(){
return name;
};
})();
console.log("main function");
var person1=new Person("bobo");
person1.setName("leishao");
alert(person1.getName());
javaScript函数与闭包的更多相关文章
- JavaScript函数、闭包、原型、面向对象
JavaScript函数.闭包.原型.面向对象 断言 单元测试框架的核心是断言方法,通常叫assert(). 该方法通常接收一个值--需要断言的值,以及一个表示该断言目的的描述. 如果该值执行的结果为 ...
- JavaScript 函数之 ------------------ 闭包
谈到闭包,人们常常会把匿名函数和闭包混淆在一起.闭包是指由权访问另一个函数作用域中的变量的函数.创建闭包的常见方式,就是在一个函数内部创建另一个函数,仍以前面的 createComparisonFun ...
- JavaScript函数及闭包
前面一片文章讲到过一点函数,了解到每声明一个函数就会产生一个作用域.而外面的作用域访问不了里面的作用域(把里面的变量和函数隐藏起来),而里面的可以访问到外面的.对于隐藏变量和函数是一个非常有用的技术. ...
- javascript函数闭包(closure)
一,首先感受下javascript函数的闭包 二,闭包 1,定义:闭包就是能够读取其他函数内部变量的函数,由于在javascript语言中,只有在函数内部的子函数才能够读取局部变量,因此可以把闭包简单 ...
- JavaScript函数之作用域 / 作用链域 / 预解析
关于作用域和作用链域的问题,很多文章讲的都很详细,本文属于摘录自己觉得对自己有价值的部分,留由后用,仅供参考,需要查看详细信息请点击我给出的原文链接查看原文件 做一个有爱的搬运工~~ -------- ...
- JavaScript权威设计--命名空间,函数,闭包(简要学习笔记十二)
1.作为命名空间的函数 有时候我们需要声明很多变量.这样的变量会污染全局变量并且可能与别人声明的变量产生冲突. 这时.解决办法是将代码放入一个函数中,然后调用这个函数.这样全局变量就变成了 局部变量. ...
- 深入理解javascript函数参数与闭包(一)
在看此文章,希望先阅读关于函数基础内容 函数定义与函数作用域 的章节,因为这篇文章或多或少会涉及函数基础的内容,而基础内容,我放在函数定义函数作用域 章节. 本文直接赘述函数参数与闭包,若涉及相关知识 ...
- 深入理解javascript原型和闭包(2)——函数和对象的关系
上文(理解javascript原型和作用域系列(1)——一切都是对象)已经提到,函数就是对象的一种,因为通过instanceof函数可以判断. var fn = function () { }; co ...
- JavaScript中的闭包和匿名函数
JavaScript中的匿名函数及函数的闭包 1.匿名函数 2.闭包 3.举例 4.注意 1.匿名函数 函数是JavaScript中最灵活的一种对象,这里只是讲解其匿名函数的用途.匿名函数:就是没 ...
随机推荐
- MVC @functions
asp.net Razor 视图具有.cshtml后缀,可以轻松的实现c#代码和html标签的切换,大大提升了我们的开发效率.但是Razor语法还是有一些棉花糖值得我们了解一下,可以更加强劲的提升我们 ...
- 挑战编程PC/UVa Stern-Brocot代数系统
/* Stern-Brocot代数系统 Stern-Brocot树是一种生成所有非负的最简分数m/n的美妙方式. 其基本方式是从(0/1, 1/0)这两个分数开始, 根据需要反复执行如下操作: 在相邻 ...
- IO流学习小结
今天刚刚看完java的io流操作,把主要的脉络看了一遍,不能保证以后使用时都能得心应手,但是最起码用到时知道有这么一个功能可以实现,下面对学习进行一下简单的总结: IO流主要用于硬板.内存.键盘等处理 ...
- MVC3中几个小知识点
1.ViewBag.Name~ViewBag.name等价,即不区分大小写.在此小心,下次见到不要奇怪,不过最好还是写成一样的比较好. 2.JS字符串不允许有换行符,\'等字符,需提前处理.
- 获得sql对应的binary
Declare @max Varbinary(max) select @Max = convert(Varbinary(max) , ' Select ' ) Print ' DECLARE @sql ...
- ASP.NET MVC3更新出错:ObjectStateManager中已存在具有同一键的对象
程序代码: [HttpPost] public ActionResult Edit(Person person) { if (ModelState.IsValid) { Person oldperso ...
- Magento 安装时文件权限 设置
http://www.magentocommerce.com/wiki/1_-_installation_and_configuration/magento_filesystem_permission ...
- js判断input为空校验
突然发现最近js发现的问题比较多,更发现我怎么快成了前端开发了?不能够啊!我后台怎么不出问题呢?我的后台是太简单了吗?mybatis-dao-service-controller返回给前台...... ...
- Be a Smart Project Manager
The key to being a smart project manager is to remember how you are going to manage your project, to ...
- iOS UPYUN(又拍云)使用总结
UPYUN,原来没用过,上个周用了一次,觉得蛮方便的,对于个人开发者,且没有服务器的,上传图片和文件,是个不二选择. 首先,先明白原理: 1.又拍云有一个上传空间,在这个空间里,有空间名称.密钥,其他 ...