闭包的实现原理和作用

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. LeetCode 896. Monotonic Array

    原题链接在这里:https://leetcode.com/problems/monotonic-array/ 题目: An array is monotonic if it is either mon ...

  2. qt ubutun各个版本下载地址

    http://download.qt.io/archive/qt/ http://mirrors.melbourne.co.uk/ubuntu-releases/

  3. C——swap

    /* swap.c */ /* function swap to swap two numbers */ #include <stdio.h> void swap(int*, int*); ...

  4. PATA1005Spell It Right

    考虑输入为0的特殊情况 参考代码: #define _CRT_SECURE_NO_WARNINGS #include<cstdio> #include<cstring> #in ...

  5. (近万字)一篇文章带你了解HTML5和CSS3开发基础与应用-适合前端面试必备

    作者 | Jeskson 来源 | 达达前端小酒馆 HTML5和CSS3开发基础与应用,详细说明HTML5的新特性和新增加元素,CSS3的新特性,新增加的选择器,新的布局,盒子模型,文本,边框,渐变, ...

  6. haproxy 配置文件详解 之 listen

    配置示例: listen admin_stats bind mode http log 127.0.0.1 local0 err stats refresh 30s stats uri /haprox ...

  7. 【BigData】Java基础_创建一个订单类

    需求描述 定义一个类,描述订单信息订单id订单所属用户(用户对象)订单所包含的商品(不定数量个商品对象)订单总金额订单应付金额:    总金额500~1000,打折85折    总金额1000~150 ...

  8. spring cloud 服务链路追踪 skywalking 6.1

    随着微服务架构的流行,服务按照不同的维度进行拆分,一次请求往往需要涉及到多个服务.互联网应用构建在不同的软件模块集上,这些软件模块,有可能是由不同的团队开发.可能使用不同的编程语言来实现.有可能布在了 ...

  9. 【Gamma】“北航社团帮”测试报告——小程序v3.0

    目录 测试计划.过程和结果 后端测试--单元测试与覆盖率 后端测试--压力测试 展示部分数据 平均数据 前端测试--小程序v3.0 新功能 各页面均可正常打开,跳转,回退 授权登录与权限检查 页面数据 ...

  10. mysql 数据库中的每张表加同一个字段(避免重复加)

    DROP PROCEDURE IF EXISTS testEndHandle; DELIMITER $$ CREATE PROCEDURE testEndHandle() BEGIN DECLARE ...