闭包的实现原理和作用

1、闭包的概念:指有权访问另一个函数作用域中的变量的函数,一般情况就是在一个函数中包含另一个函数。

2、闭包的作用:访问函数内部变量、保持函数在环境中一直存在,不会被垃圾回收机制处理

因为函数内部声明 的变量是局部的,只能在函数内部访问到,但是函数外部的变量是对函数内部可见的,这就是作用域链的特点了。

子级可以向父级查找变量,逐级查找,找到为止

 function  bar(){
//外层函数声明的变量
var value=1; function foo(){
console.log(value);
}
return foo();
};
var bar2=bar;
//实际上bar()函数并没有因为执行完就被垃圾回收机制处理掉
//这就是闭包的作用,调用bar()函数,就会执行里面的foo函数,foo这时就会访问到外层的变量
bar2();

因此我们可以在函数内部再创建一个函数,这样对内部的函数来说,外层函数的变量都是可见的,然后我们就可以访问到他的变量了。

3、闭包的优点:

  • 方便调用上下文中声明的局部变量
  • 逻辑紧密,可以在一个函数中再创建个函数,避免了传参的问题

4、闭包的缺点:

因为使用闭包,可以使函数在执行完后不被销毁,保留在内存中,如果大量使用闭包就会造成内存泄露,内存消耗很大

实际开发中JS闭包的应用

1。在函数外使用函数内的变量 .函数作为返回值   (闭包作用:避免变量被环境污染)

 function F1(){
var a = 100;
return function(){
console.log(a)
}
}
var f1 =F1();
var a = 200;
f1()//100
 function init(){
var name = "hello world";//name是一个被init创建的局部变量
function sayName(){//sayName是一个内部函数,闭包
alert(name);//使用了父级函数声明的变量name
}
sayName();
}
init();//"hello world"

2.函数作为参数传递

 function F1(){
var a = 100;
return function(){
console.log(a)
}
}
var f1 =F1();
function F2(fn){
var a = 200;
fn();
}
F2(f1); // 100

3.将函数与其所操作的某些数据关联起来,通常,你使用只有一个方法的对象的地方,都可以使用闭包

 // 改变dom样式
document.getElementById("a").onclick = setSize(12);
document.getElementById("b").onclick = setSize(18);
document.getElementById("c").onclick = setSize(22);
function setSize(fontSize){
return function(){
document.body.style.fontSize = fontSize + 'px';
}
}

4.用闭包模拟私有方法

 //这三个公共函数是共享同一个环境的闭包。多亏 JavaScript 的词法作用域,它们都可以访问 privateCounter 变量和 changeBy 函数。
var makeCounter = function () {
var privateCounter = 0;
function changeBy(val){
privateCounter += val;
};
return {
increment: function(){
changeBy(1);
},
decrement: function(){
changeBy(-1);
},
value: function(){
return privateCounter;
}
}
};
var Counter1 = makeCounter();
var Counter2 = makeCounter();
Counter1.increment();
console.log(Counter1.value());//1 每次调用其中一个计数器时,通过改变这个变量的值,会改变这个闭包的词法环境。然而在一个闭包内对变量的修改,不会影响到另外一个闭包中的变量。
console.log(Counter2.value());//0 以这种方式使用闭包,提供了许多与面向对象编程相关的好处 —— 特别是数据隐藏和封装。

5.循环里面的闭包

怎么才能实现输出0-5呢?

 for (var i = 0; i < 5; i++) {
setTimeout(function () {
console.log(i);
}, 1000 * i);
}//
//方法一,makeCallback函数为每一个回调创建一个新的词法环境。
function makeCallback(i) {
return function() {
console.log(i)
};
}
for(var i=0;i<10;i++){
setTimeout(makeCallback(i),1000)
}
//另一种方法使用了匿名闭包
for(var i=0;i<10;i++){
(function(i){
setTimeout(function () {
console.log(i)
},1000)
})(i)
}
 //使用let声明变量
for (let i = 0; i < 5; i++) {
setTimeout(function () {
console.log(i);
}, 1000 * i);
}

5.Javascript闭包得实现原理和作用的更多相关文章

  1. 前端知识体系:JavaScript基础-作用域和闭包-闭包的实现原理和作用以及堆栈溢出和内存泄漏原理和相应解决办法

    闭包的实现原理和作用 闭包: 有权访问另一个函数作用域中的变量的函数. 创建闭包的常见方式就是,在一个函数中创建另一个函数. 闭包的作用: 访问函数内部变量.保持函数在环境中一直存在,不会被垃圾回收机 ...

  2. JavaScript闭包(二)——作用

    一.延迟调用 当在一段代码中使用 setTimeout 时,要将一个函数的引用作为它的第一个参数,而将以毫秒表示的时间值作为第二个参数. 但是,传递函数引用的同时无法为计划执行的函数提供参数.可以在代 ...

  3. JavaScript的闭包是什么意思以及作用和应用场景

    JavaScript闭包 1.什么是闭包 百度百科对于闭包的解释是:闭包是指可以包含自由(未绑定到特定对象)变量的代码块:这些变量不是在这个代码块内或者任何全局上下文中定义的,而是在定义代码块的环境中 ...

  4. 我也谈javascript闭包的原理理解

    参考原文:http://www.oschina.net/question/28_41112 前言:还是一篇入门文章.Javascript中有几个非常重要的语言特性——对象.原型继承.闭包.其中闭包 对 ...

  5. 前端知识体系:JavaScript基础-作用域和闭包-this的原理以及几种使用场景

    一.问题由来: var obj = { foo: function () { console.log(this.bar) }, bar: 1 }; var foo = obj.foo; var bar ...

  6. JavaScript ---- 闭包(什么是闭包,为什么使用闭包,闭包的作用)

    经常被问到什么是闭包? 说实话闭包这个概念很难解释.JavaScript权威指南里有这么一段话:“JavaScript函数是将要执行的代码以及执行这些代码作用域构成的一个综合体.在计算机学术语里,这种 ...

  7. [JavaScript闭包]Javascript闭包的判别,作用和示例

    闭包是JavaScript最重要的特性之一,也是全栈/前端/JS面试的考点. 那闭包究竟该如何理解呢? 如果不爱看文字,喜欢看视频.那本文配套讲解视频已发送到B站上供大家参考学习. 如果觉得有所收获, ...

  8. JavaScript闭包(Closure)

    JavaScript闭包(Closure) 本文收集了多本书里对JavaScript闭包(Closure)的解释,或许会对理解闭包有一定帮助. <你不知道的JavsScript> Java ...

  9. 理解JAVASCRIPT 闭包

    最近去面试了一家企业,结果非常灰心丧气,于是周末给自己定了一个目标 学好一门,学精通一门.不求多,只求懂. 最近看到一个概念“闭包”. 什么是闭包呢? 简单一点就是:看得到多和看得到少的区别. 上面这 ...

随机推荐

  1. reactnative遇到的问题总结

    1.View中出现文本报错,View等标签中不能出现字符串文本,字符串文本需要包在Text中,遇到如下错误 下面是问题代码: let rightTitle = this.props.rightTitl ...

  2. Python进阶-I 初识函数(function)

    函数 在java中叫方法. 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段. 函数能提高应用的模块性,和代码的重复利用率.你已经知道Python提供了许多内建函数,比如print() ...

  3. VQA视觉问答基础知识

    本文记录简单了解VQA的过程,目的是以此学习图像和文本的特征预处理.嵌入以及如何设计分类loss等等. 参考资料: https://zhuanlan.zhihu.com/p/40704719 http ...

  4. docker 挂载主机目录 -v 和 --mount区别

    使用-v  时,如果宿主机上没有这个文件,也会自动创建, 但是如果使用--mount时,宿主机中没有这个文件会报错找不到这个文件,并创建失败

  5. Shell脚本之五 基本运算符

    Shell 和其他编程语言一样,支持多种运算符,包括: 算数运算符 关系运算符 布尔运算符 字符串运算符 文件测试运算符 原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 ...

  6. 记一次node节点异常排查

    一.背景 公司进行kubernetes服务重启演练,集群重启后所有服务正常,仅node2节点处于notready状态 二.排查过程 查看对应节点的详细信息,发现kubelet一直处于starting状 ...

  7. Maven 教程(15)— 实现多个项目关联自动化构建(maven-invoker-plugin插件的使用)

    原文地址:https://blog.csdn.net/liupeifeng3514/article/details/79726664 一.场景设想一个团队正在开发一个项目 bus-core-api,并 ...

  8. jvm jdk jre 关系

    JDK : Java Development ToolKit(Java开发工具包).JDK是整个JAVA的核心,包括了Java运行环境(Java Runtime Envirnment),一堆Java工 ...

  9. PG数据库CPU和内存满负荷运转优化案

    1.问题描述 某客户系统采用三层架构:数据库—应用服务—前端应用.其中数据库使用PostgreSQL 10.0作为数据库软件.自周四起,服务器的CPU与内存使用率持续处于过饱合状态,并因此导致了数次宕 ...

  10. linux lnmp环境下 安装apache教程

    linux lnmp环境下 安装apache教程 源码安装 apr ,apr-util 安装apache要用<pre>wget http://mirrors.cnnic.cn/apache ...