js匿名函数和闭包总结

一、总结

一句话总结:匿名函数的最主要作用是创建闭包,闭包就是将函数内部和函数外部连接起来的一座桥梁。内层的函数可以使用外层函数的所有变量,即使外层函数已经执行完毕。闭包可以用来模仿块级作用域等等。

匿名函数 闭包:匿名函数的最主要作用是创建闭包,闭包就是将函数内部和函数外部连接起来的一座桥梁。内层的函数可以使用外层函数的所有变量,即使外层函数已经执行完毕。闭包可以用来模仿块级作用域等等

1、js匿名函数基本格式?

匿名函数 赋值 变量
立即执行 匿名函数 ()()
return 匿名函数

没有名字 可以赋值

  //情况1.把匿名函数赋值给变量
var fn=function (){
alert('我是匿名函数')
}
alert(fn) //会将函数表达式输出
fn() //情况2.匿名函数通过表达式自我执行
(function (){
alert('我是匿名函数')
}
)()
    var name='The Window';
var obj={
name:'my obj',
get:function(){
return function(){
return this.name;
}
}
} alert(obj.get()()) //这次返回的是全局变量 'The Window'
alert(obj.get().call(obj))//这次又返回的是'my obj',因为call()强制改变了this的指向

2、js 中的匿名函数如何自己运行?

(匿名函数)()

因为js中的()可以将函数代码段运行,也可以将变量转化为函数

  (function(m,n){
alert(m+n)
})(1000,1000)

匿名函数

没有函数名字的函数

  1. 单独的匿名函数是无法运行和调用的
  2. 可以把匿名函数赋值给变量
  3. 通过表达式自我执行,语法:(匿名函数)()
  4. 匿名函数传递参数,语法:(匿名函数)(参数)

3、js中的匿名函数如何传递参数?

()() 括号 传参

匿名就是()()的格式

 //匿名函数传递参数
function myfn(m,n){
alert(m+n)
}
myfn(100,100); (function(m,n){
alert(m+n)
})(1000,1000)

4、js变量后的()可以表示哪些意思?

变量 变成 方法
执行 匿名函数

a、将变量变成方法

b、放在匿名函数后面,用来执行匿名函数,这样做的话匿名函数本身也要用括号扩起来,

5、js中的闭包是什么?

函数 嵌套 匿名函数

在一个函数中嵌套了一个匿名函数,匿名函数可以访问这个函数里面的变量

闭包的相关概念

    • 闭包的英文单词是closure,是指有权访问另一个函数作用域中变量的函数。
    • 在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。内层的函数可以使用外层函数的所有变量,即使外层函数已经执行完毕。
    • 这是JavaScript中非常重要的一部分知识,因为使用闭包可以大大减少我们的代码量,使我们的代码看上去更加清晰等等,总之功能十分强大。

注:这些概念了解即可,接下来我们将通过实例来进行了解。

6、匿名函数最大的作用是什么?

创建闭包

闭包的相关概念

    • 闭包的英文单词是closure,是指有权访问另一个函数作用域中变量的函数。
    • 在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。内层的函数可以使用外层函数的所有变量,即使外层函数已经执行完毕。
    • 这是JavaScript中非常重要的一部分知识,因为使用闭包可以大大减少我们的代码量,使我们的代码看上去更加清晰等等,总之功能十分强大。

注:这些概念了解即可,接下来我们将通过实例来进行了解。

7、alert(myfn);alert(myfn());alert(myfn()())得到的结果分别是什么?

整个函数表达式 匿名函数表达式 执行结果
    function myfn(){

      return function (){

        return('**********')

      }
} //alert(myfn) //输出整个函数表达式
//alert(myfn()) //输出匿名函数表达式 //调用方式1
alert(myfn()())

8、闭包的用途是什么?

局部变量 常驻内存

闭包的相关知识点

  1. 常见的方式是在函数内部创建另一个函数
  2. 闭包的第一个用途:通过闭包可以访问局部变量
  3. 闭包的第二个用途:可以让局部变量的值始终保持在内存中
    • 优点:可以把局部变量驻留在内存中,可以避免使用全局变量;

      全局变量在复杂程序中会造成许多麻烦(比如命名冲突,垃圾回收等),所以推荐使用私有的,封装的局部变量。而闭包可以实现这一点。

    • 缺点:由于闭包里作用域返回的局部变量资源不会被立刻销毁回收,所以可能会占用更多的内存;所以过度使用闭包会导致性能下降;
  4. 循环函数中的匿名函数和闭包问题

9、add()()的方式为何无法让闭包实现函数局部变量的累加?

初始化
// add()();add()();add()();//这种调用方式会出错,因为每次调用 num都会初始化一次;
var fn=add() ;fn();fn();fn();//只在这里初始化一次,后边调用的时候执行的是里边的匿名函数
  function add(){

      var num= 100; // 这里改为局部变量;

       return function(){
num++;
alert(num);
} }; // add()();add()();add()();//这种调用方式会出错,因为每次调用 num都会初始化一次; var fn=add()//只在这里初始化一次,后边调用的时候执行的是里边的匿名函数 fn();fn();fn(); fn=null //应及时解除引用,否则会占用更多存

10、如何解决闭包将局部变量注入内存的缺点?

赋值 null
fn=null //应及时解除引用,否则会占用更多存

闭包的相关知识点

  1. 常见的方式是在函数内部创建另一个函数
  2. 闭包的第一个用途:通过闭包可以访问局部变量
  3. 闭包的第二个用途:可以让局部变量的值始终保持在内存中
    • 优点:可以把局部变量驻留在内存中,可以避免使用全局变量;

      全局变量在复杂程序中会造成许多麻烦(比如命名冲突,垃圾回收等),所以推荐使用私有的,封装的局部变量。而闭包可以实现这一点。

    • 缺点:由于闭包里作用域返回的局部变量资源不会被立刻销毁回收,所以可能会占用更多的内存;所以过度使用闭包会导致性能下降;
  4. 循环函数中的匿名函数和闭包问题
  function add(){

      var num= 100; // 这里改为局部变量;

       return function(){
num++;
alert(num);
} }; // add()();add()();add()();//这种调用方式会出错,因为每次调用 num都会初始化一次; var fn=add()//只在这里初始化一次,后边调用的时候执行的是里边的匿名函数 fn();fn();fn(); fn=null //应及时解除引用,否则会占用更多存

11、js如何让循环中的匿名函数和闭包接收到的i正确?

匿名函数 立即执行
匿名函数 内 匿名函数 传参数

函数内部的匿名函数立即执行

    //让匿名函数立即执行来赋值
function fun(){
var arr=[];
for(var i=0; i<5; i++){
arr[i]=(function(){
return '元素'+i;
})()
}
return arr
}
var Bb=fun()
alert(Bb.length)
alert(Bb)
// for(var i=0; i<5; i++){ // alert(Bb[i])
// }

匿名函数内部加一层匿名函数(加传参):常见结构

   //通过闭包让局部变量驻留在内存中
function fun(){
var arr=[];
for(var i=0; i<5; i++){
arr[i]=function(n){
return function(){
return '元素'+n;
}
}(i)
}
return arr
}
var Bb=fun()
//alert(Bb.length)
// alert(Bb[0]())
for(var i=0; i<5; i++){
//alert(Bb[i])
alert(Bb[i]())
}
//这次成功的输出了 ‘元素0 元素1 元素2 元素3 元素4 ’,而不再都是[元素5]
/*
1.这里的匿名函数有一个参数 n,也就是最终将返回的结果数值;
2.在调用每个匿名函数时传入变量i
3.变量i的当前值会赋值给n,
4.匿名函数内部创建并返回了一个访问n的闭包
5.如此数组arr中的每个函数中都有了自己的n变量的一个副本(闭包可以将局部变量贮存在内存中) */

闭包的相关知识点

  1. 常见的方式是在函数内部创建另一个函数
  2. 闭包的第一个用途:通过闭包可以访问局部变量
  3. 闭包的第二个用途:可以让局部变量的值始终保持在内存中
    • 优点:可以把局部变量驻留在内存中,可以避免使用全局变量;

      全局变量在复杂程序中会造成许多麻烦(比如命名冲突,垃圾回收等),所以推荐使用私有的,封装的局部变量。而闭包可以实现这一点。

    • 缺点:由于闭包里作用域返回的局部变量资源不会被立刻销毁回收,所以可能会占用更多的内存;所以过度使用闭包会导致性能下降;
  4. 循环函数中的匿名函数和闭包问题

12、js匿名函数中的this指代的是谁?

window

闭包中的this问题

  • 之前的课程中讲过this是在运行时基于函数的执行环境来绑定的
  • 全局函数中的this是window,而当函数作为某个对象的方法调用时,this就是指的那个对象......
  • 匿名函数的执行环境具有全局性,this通常是指向window的。
    • 可以使用对象冒充强制改变this的指向
    • 将this赋值给一个变量,闭包访问这个变量
    var name='The Window';
var obj={
name:'my obj',
get:function(){
return function(){
return this.name;
}
}
} alert(obj.get()()) //这次返回的是全局变量 'The Window'

13、如何让匿名函数中的this指向当前对象?

对象冒充 闭包访问

匿名函数的执行环境具有全局性,this通常是指向window的。

  • 可以使用对象冒充强制改变this的指向
  • 将this赋值给一个变量,闭包访问这个变量

对象冒充

    var name='The Window';
var obj={
name:'my obj',
get:function(){
return function(){
return this.name;
}
}
} alert(obj.get()()) //这次返回的是全局变量 'The Window'
alert(obj.get().call(obj))//这次又返回的是'my obj',因为call()强制改变了this的指向

闭包访问

  var name='The Window';
var obj={
name:'my obj',
get:function(){
//这里的this指的是对象,这里为obj
var self=this
return function(){
//闭包里的this指的是window
return self.name;
}
}
} alert(obj.get()())

14、如何模仿块级作用域?

立即执行 匿名函数

用匿名函数

将需要放进块级作用域的东西放进一个立即执行的匿名函数里面

js没有块级作用域代码

  function myfun() {

    for(var i=0;i<5;i++){

    }  //i不会因为离开了for块就失效;

    var i; //重新声明后i还是5,

    alert(i)  //此时的i=5
}

模仿块级作用域

  <script>
//模仿块级作用域
function myfun() { (function(){
for(var i=0;i<5;i++){
alert(i)
}
})() // 这里定义并立即调用了一个匿名函数; alert(i)
//此时的i已结不存在 会报错:'i is not defined'
}
myfun()
</script>

块级作用域又叫私有作用域,但是JS没有块级作用域的概念;这意味着在块语句(比如for语句)中定义的变量,不会因为离开了for块就失效。

  • 使用了块级作用域后,匿名函数中定义的任何变量,都会在执行结束时被销毁;
  • 一般来说,我们都应该尽可能少向全局作用域中添加变量和函数;过多的全局变量和函数很容易导致命名冲突
  • 使用块级作用域,每个开发者既可以使用自己的变量,又不必担心搞乱全局作用域;
  • 在全局作用域中使用块级作用域可以减少闭包占用的内存问题.

15、js对象如何创建私有变量和类似其它语言的get、set方法(特权方法)?

私有变量 对象 private 权限
特权方法 this 属性 匿名方法

this方式定义的变量方法外部可以访问

var方式定义的吧变量方法外部无法访问

私有变量也就是例如java对象的private权限的变量

var name='张三'; // 私有变量;

特权方法其实是this的一个属性,这个属性指向一个匿名方法,因为是当前对象的属性,所以外部可以访问

this.getname=function(){ // 对外公共的特权方法;
return name;
}

私有变量

JavaScript没用私有属性的概念;所有的属性都是公用的;

私有变量的概念:在任何函数中定义的变量,都是私有变量,因为不能在函数外部访问这些变量;

  • 私有变量:包括函数的参数/局部变量和在函数内部定义的其他函数;
  • 特权方法:内部创建一个闭包,闭包可以访问私有变量;因此创建用于访问私有变量的公用方法,称作特权方法
  • 可以通过构造方法传参来访问私有变量

    这种方法的缺点是会为每一个实例创建一组新的方法,不能实现共享。

  function People(){
var name='张三'; // 私有变量;
var age='30';
function say(){ // 私有函数;
return '我是......';
} this.getname=function(){ // 对外公共的特权方法;
return name;
} this.getsay=function(){
return say()
}
}
var p=new People()
alert(p.getname())
alert(p.getsay())

16、对象创建的时候,用this声明的属性和用var定义的局部变量创建的对象是不同的?

this 属性 访问 变量 public 权限
var 函数变量 无法访问 变量 private 权限

使用this方式的话是对象的属性,外部可以轻松访问变量,相对于java中给变量设置权限public

使用var方式的话,是函数变量(局部变量,私有变量),函数外部无法访问,相对于java中非变量设置private权限,使用特权方法可以访问,特权方法相对于get/set方法,

使用this方式

  function People(){
this.name='张三';
this.age='30';
this.say=function (){
return '我是'+this.name+'......';
}
}

使用var方式

function People(){
var name='张三'; // 私有变量;
var age='30';
function say(){ // 私有函数;
return '我是......';
} this.getname=function(){ // 对外公共的特权方法;
return name;
} this.getsay=function(){
return say()
}
}

17、js对象如何创建静态变量(静态私有变量)?

立即执行的闭包 原型 特权方法 块级作用域

静态私有变量

通过块级作用域(私有作用域)中定义私有变量或函数,创建对外公共的特权方法;

  • 首先创建私有作用域
  • 定义私有变量或函数
  • 定义构造函数和特权方法
  • 这种方式创建的私有变量因为使用原型而实现共享。
  • 同时由于共享,实例也就没有自己的私有变量。
   (function(){
var name='张三';
User=function(){} //构造函数
User.prototype.getName=function(){
return name
}
User.prototype.setName=function(value){
name=value
};
})() var VIP1=new User() //因为Uer()是私有函数,所以外部无法访问。
//alert(VIP1.getName())
VIP1.setName('李四')
//alert(VIP1.getName()) var VIP2=new User()
alert(VIP2.getName())

18、js对象为何会用到静态私有变量(静态方法)?

共享

共享肯定是要通过原型的

私有变量方式的缺点是会为每一个实例创建一组新的方法,不能实现共享。

19、下面代码是匿名函数么?

函数 名字
get:function(){
return this.name;
}
}

这只是json写法的对象中的函数而已,就是讲函数赋值给一个变量,这个函数是有名字的,所以不叫闭包

      get:function(){
return function(){
return this.name;
}
}

这个才是闭包

这个不是

      var obj={
name:'my obj',
get:function(){
return this.name;
}
}
alert(obj.get()) //返回 'my obj'

这个是

    var name='The Window';
var obj={
name:'my obj',
get:function(){
return function(){
return this.name;
}
}
} alert(obj.get()()) //这次返回的是全局变量 'The Window'
alert(obj.get().call(obj))//这次又返回的是'my obj',因为call()强制改变了this的指向

二、内容在总结中

 

js匿名函数和闭包总结的更多相关文章

  1. js匿名函数与闭包作用

    http://www.jb51.net/article/79238.htm 1 闭包允许内层函数引用父函数中的变量,但是该变量是最终值 当mouseover事件调用监听函数时,首先在匿名函数( fun ...

  2. js匿名函数,闭包

    http://www.cnblogs.com/chenxianbin89/archive/2010/01/28/1658392.html

  3. js循环函数中的匿名函数和闭包问题(匿名函数要用循环中变量的问题)

    js循环函数中的匿名函数和闭包问题(匿名函数要用循环中变量的问题) 一.总结 需要好好看下面代码 本质是因为匿名函数用到了循环中的变量,而普通方式访问的话,匿名函数的访问在循环之后,所以得到的i是循环 ...

  4. JS匿名函数的理解

    js匿名函数的代码如下:(function(){ // 这里忽略jQuery 所有实现 })(); 半年前初次接触jQuery 的时候,我也像其他人一样很兴奋地想看看源码是什么样的.然而,在看到源码的 ...

  5. php的匿名函数和闭包函数

    php的匿名函数和闭包函数 tags: 匿名函数 闭包函数 php闭包函数 php匿名函数 function use 引言:匿名函数和闭包函数都不是特别高深的知识,但是很多刚入门的朋友却总是很困惑,因 ...

  6. 匿名函数、闭包、lambda表达式、Block

    C#有lambda.匿名函数,js有匿名函数.闭包,OC中有block,看到这是不是心中有一万个草泥马在跑,不过它们这些都是换汤不换药,不同语言名字不一样. 从功能性上说lambda和closure( ...

  7. javascript进阶课程--第三章--匿名函数和闭包

    javascript进阶课程--第三章--匿名函数和闭包 一.总结 二.学习要点 掌握匿名函数和闭包的应用 三.匿名函数和闭包 匿名函数 没有函数名字的函数 单独的匿名函数是无法运行和调用的 可以把匿 ...

  8. js匿名函数测试

    js匿名函数测试 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> < ...

  9. JS匿名函数自执行函数

    JS匿名函数自执行函数:(function(){})();(function(){}) 这是一个函数,函数后面接(),则是调用函数 比如(function(arg){console.log(arg); ...

随机推荐

  1. Kintone学习

    kintone JavaScript编码指南 编码的注意地方: 文字编码 使用 utf-8

  2. 2018-2019-2 20165209 《网络对抗技术》Exp7: 网络欺诈防范

    2018-2019-2 20165209 <网络对抗技术>Exp7: 网络欺诈防范 1 基础问题回答和实验内容 1.1基础问题回答 (1)通常在什么场景下容易受到DNS spoof攻击. ...

  3. 基于webview的Hybrid app和React Native及html5

    基于webview的Hybrid app和React Native及html5 React Native 结合了 Web 应用和 Native 应用的优势,可以使用 JavaScript 来开发 iO ...

  4. 20145322 Exp5 Adobe阅读器漏洞攻击

    20145322 Exp5 Adobe阅读器漏洞攻击 实验过程 IP:kali:192.168.1.102 windowsxp :192.168.1.119 msfconsole进入控制台 使用命令为 ...

  5. 实验二 Java 面向对象程序设计

    实验内容 1 初步掌握单元测试和TDD 2 理解并掌握面向对象三要素:封面,继承,多态 3 初步掌握UML建模 4 熟悉SOLID原则 5 了解设计模式 (一)单元测试 D

  6. Codeforces Round#413 Problem A - C

    Problem#A Carrot Cakes vjudge链接[here] (偷个懒,cf链接就不给了) 题目大意是说,烤面包,给出一段时间内可以考的面包数,建第二个炉子的时间,需要达到的面包数,问建 ...

  7. 主引导记录MBR的结构和作用

    MBR磁盘分区都有一个引导扇区,称为主引导记录,英文简称为MBR.1. MBR的结构MBR扇区位于整个硬盘的第一个扇区:按照C/H/S地址描述,即0柱面〇磁头1扇 区:按照LBA地址描述即0扇区.它是 ...

  8. 精巧好用的DelayQueue 转

    我们谈一下实际的场景吧.我们在开发中,有如下场景 a) 关闭空闲连接.服务器中,有很多客户端的连接,空闲一段时间之后需要关闭之.b) 缓存.缓存中的对象,超过了空闲时间,需要从缓存中移出.c) 任务超 ...

  9. com.fasterxml.jackson.databind.JsonMappingException: No content to map due to end-of-input

    作者原创,转载请注明转载地址 第一次遇到该异常,在网上搜了很长时间也没找到解决答案,特此记录 1.异常展示: com.fasterxml.jackson.databind.JsonMappingExc ...

  10. 解决复制到keil编辑器中汉字出现乱码情况

    https://blog.csdn.net/dxuehui/article/details/51123372 1.在菜单栏中选择'Edit'选项. 2.'Edit'选项中选择'Configuratio ...