es6有闭包吗

教程操作环境:windows7系统、ECMAScript 6版、Dell G3电脑。

一、变量作用域

变量根据作用域的不同分为两种:全局变量和局部变量。

  • 函数内部可以使用全局变量。

  • 函数外部不可以使用局部变量。

  • 当函数执行完毕,本作用域内的局部变量会销毁。

二、什么是闭包?

es6中,闭包(closure)指有权访问另一个函数作用域中变量的函数。简单理解:一个作用域可以访问另外一个函数内部的局部变量。

闭包:在一个函数内部创建另一个函数,把内嵌的函数称为闭包,它可以访问外部函数的局部变量

	// fun 这个函数作用域 访问了另外一个函数 fn 里面的局部变量 num
    function fn(){
        let num = 10
        function fun(){
            console.log(num)
        }
        fun()
    }
    fn() //10

闭包的主要作用:延伸了变量的作用范围。

	// fn 外面的作用域可以访问fn 内部的局部变量
    function fn(){
        let num = 10
        // 方法一: 先定义再返回函数
        function fun(){
            console.log(num)
        }
        return fun //返回 fun函数
    }
    let f = fn()
    f() //10
	// fn 外面的作用域可以访问fn 内部的局部变量
    function fn(){
        let num = 10
        // 方法二: 直接返回函数
        return function(){
            console.log(num)
        }
    }
    let f = fn()
    f() //10

三、闭包的使用场景

(1)用来返回值

//以闭包的形式将 name 返回
function fun(){
    let name = 'woniu'

    //定义闭包
    return function f1(){
        return name
    }
}

let ft = fun() //因为fun函数的返回值是f1函数,ft实质是一个函数

let na = ft()  //调用ft函数,实际调用的就是f1函数
console.log(na); //woniu

(2)函数赋值:在函数内部定义函数表达式

var f2
function fn(){
    let name = '曹操'
    f2 = function(){ //闭包,将外部函数的name变量作为闭包的返回值
        return name
    }
}
fn() //必须先调用fn函数,否则f2不是一个函数
console.log(f2());  //曹操

(3)把闭包作为函数的参数

function fn(){
    let name = '蜗牛学苑'

    //定义闭包
    return function callback(){
        return name
    }
}

let f1 = fn() //将fn函数的返回值callback赋给f1
function f2(temp){
    console.log(temp()) //输出temp函数的返回值,实际调用了闭包callback
}
//调用f2函数:将f1作为实参传递给temp
f2(f1)

(4)立即执行函数中使用闭包

//立即执行函数
(function(){
    let name = '蜗牛学苑'
    let f1 = function(){
        return name
    }

    fn2(f1) //调用fn2函数,将闭包f1作为实参传递给fn2函数
})()

function fn2(temp){  //temp是一个形参,接收f1
    console.log(temp()); //对temp的调用,实际调用的是闭包f1
}

(5)循环赋值

(function(){
    for (let i = 1; i <= 10; i++) {
        (
            function(j){
                setTimeout(function(){
                    console.log(j);
                },j*1000)
            }
        )(i)
    }
})()

(6)将闭包封装到对象中

function fun(){
    let name = '蜗牛学苑'
    setName = function(na){ //setName是闭包,用来设置外部函数的变量值
        name = na
    }
    getName = function(){ //getName是闭包,用来返回外部函数的变量值
        return name 
    }

    //外部fun函数的返回值,将闭包封装到对象中返回
    return {
        setUserName:setName,
        getUserName:getName
    }
}
let obj =fun() //将fun函数返回值(对象)赋给obj
console.log('用户名:',obj.getUserName()) //蜗牛学苑
obj.setUserName('石油学苑')
console.log('用户名:',obj.getUserName()) //石油学苑

(7)通过闭包实现迭代

let arr = ['aa','bb','cc']
function fn(temp){ //外部函数的返回值是闭包
    let i = 0
    //定义闭包:迭代获取数组元素并返回
    return function(){
        return temp[i++] || '数组已经遍历结束'
    }
}

let f1 = fn(arr)
console.log(f1()) //aa
console.log(f1()) //bb
console.log(f1()) //cc
console.log(f1()) //数组已经遍历结束

(8)、首次区分(相同的参数,函数不会重复执行)

var fn = (function(){
    var arr = [] //用来缓存的数组
    return function(val){
        if(arr.indexOf(val) == -1){ //缓存中没有则表示需要执行
            arr.push(val) //将参数push到缓存数组中
            console.log('函数被执行了',arr);  //这里写想要执行的函数
        } else {
            console.log('此次函数不需要执行');
        }
        console.log('函数调用完打印一下,方便查看缓存的数组:',arr);
    }
})()

fn(10)
fn(10)
fn(1000)
fn(20)
fn(1000)

注意

(1)搞清除谁是闭包函数

(2)分清楚闭包的返回值、外部函数的返回值

四、闭包总结

  • 闭包是什么:闭包是一个函数(一个作用域可以访问另外一个函数的局部变量)。

  • 闭包的作用是什么:延伸变量的作用范围。

没有产生闭包,因为并没有局部变量,所以访问到的是全局变量 The Window

let name = 'The Window'
    let object = {
        name: 'My Object',
        getNameFunc(){
            return function(){
                return this.name
            }
        }
    }
    let f = object.getNameFunc()
    console.log(f()) //The Window

产生了闭包:因为 this 在函数内部被赋值给了 that,指向的是 object 这个对象。

	let name = 'The Window'
    let object = {
        name: 'My Object',
        getNameFunc(){
            let that = this
            return function(){
               return that.name
            }
        }
    }
    let f = object.getNameFunc()
    console.log(f()) //My Object

使用闭包的注意点

1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。

2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。

【推荐学习javascript视频教程】

以上就是es6有闭包吗的详细内容,更多请关注编程网其它相关文章!

--结束END--

本文标题: es6有闭包吗

本文链接: https://www.lsjlt.com/news/173538.html (转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢

  • es5和es6属于JavaScript语言吗

    这篇文章主要讲解了“es5和es6属于JavaScript语言吗”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“es5和es6属于JavaScript语言吗”吧!
    阅读数:638 es6 javascript es5
  • JavaScript ES6异步函数有哪些

    本篇内容主要讲解“JavaScript ES6异步函数有哪些”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“JavaScript ES6异步函数有哪些”吧!异步功能由两部分组成:1)以函数为前缀的
    阅读数:305 es6 javascript
  • 关于前端JavaScript ES6详情

    这篇文章主要介绍了关于前端JavaScript中的ES6,ES6是一个泛指,含义是 5.1 版以后的 JavaScript 的下一代标准,涵盖了 ES2015、ES2016、ES2017语法标准,ES6新特性目前只有在一些较新版本浏览器得到支持,老版本浏览器里面运行我们需要将ES6转换为ES5
  • JavaScript ES6 Module模块详解

    这篇文章主要介绍了ES6新特性之模块Module用法,简要说明了模块Module的概念、功能并结合实例形式分析了模块Module的使用方法与相关注意事项,需要的朋友可以参考下
    阅读数:583 JavaScript Module ES6 Module
  • JavaScript ES6默认和休息参数有哪些

    本篇内容介绍了“JavaScript ES6默认和休息参数有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!默认参数在创建具有应具有默认值
    阅读数:850 es6 javascript
  • JavaScript之ES6常用基础知识有哪些

    这篇文章主要介绍了JavaScript之ES6常用基础知识有哪些,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。ES6 let与const及其相关块级作用域ES6新增了块级作用
    阅读数:207 javascript es6
  • javascript es6数组方法是什么

    这篇文章主要介绍“javascript es6数组方法是什么”,在日常操作中,相信很多人在javascript es6数组方法是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”javascript es6数
    阅读数:298 javascript
  • javascript ES6中箭头函数注意细节有哪些

    小编给大家分享一下javascript ES6中箭头函数注意细节有哪些,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!前言ES6标准新增了一种新的函数:Arrow
    阅读数:685 javascript es6
  • JavaScript中ES6相关知识有哪些

    这篇文章主要介绍“JavaScript中ES6相关知识有哪些”,在日常操作中,相信很多人在JavaScript中ES6相关知识有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”JavaScript中ES6相
    阅读数:640 es6 javascript
  • Javascript的ES5,ES6的7种继承详解

    这篇文章主要为大家详细介绍了Javascript的ES5,ES6的7种继承,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
  • 如何将JavaScript代码改成ES6语法

    这篇文章给大家分享的是有关如何将JavaScript代码改成ES6语法的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。目录* 核心例子* 修改成静态变量(const)或块级变量(let) * 开始修改 * 疑
    阅读数:405 javascript es6
  • JavaScript的CommonJS、AMD、CMD、ES6实例分析

    本篇内容主要讲解“JavaScript的CommonJS、AMD、CMD、ES6实例分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“JavaScript的CommonJS、AMD、CMD、ES
    阅读数:575 javascript commonjs amd
  • JavaScript ES6中class定义类实例方法

    ES6提供了更接近面向对象(注意:javascript本质上是基于对象的语言)语言的写法,引入了Class(类)这个概念,作为对象的模板,下面这篇文章主要给大家介绍了关于JavaScript ES6中class定义类的相关资料,需要的朋友可以参考下
  • JavaScript ES6模块导入和导出的方法

    ES6在语言标准的层面上实现了模块功能,而且实现的相当简单,完全可以取代CommonJS和AMD规范,成为浏览器和服务器通用的模块解决方案,下面这篇文章主要给大家介绍了关于ES6模块导入和导出的方法,需要的朋友可以参考下
  • 结合 ES6 类编写JavaScript 创建型模式

    这篇文章主要介绍了结合ES6类编写JavaScript创建型模式,本文开始系统性的对20多种JavaScript 设计模式进行简单概述,然后结合ES6类的方式来编写实例代码展示其使用方式,需要的朋友可以参考一下
  • javascript中es6如何判断数组是否含有相同的值

    这篇文章主要介绍了javascript中es6如何判断数组是否含有相同的值,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。判断方法:1、将数组转为
    阅读数:159 javascript es6
  • ES6 javascript中Class类继承的示例分析

    小编给大家分享一下ES6 javascript中Class类继承的示例分析,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!具体如下:1. 基本用法Class 之间可以通过extends关键字实现继承, 这比 ES5 的通过修
    阅读数:682 es6 class类 js
  • ES6下javascript解构赋值常见用法总结

    这篇文章主要介绍了在ES6下javascript赋值常见用法总结,需要的朋友可以参考下
  • ES6中javascript如何实现异步操作

    这篇文章主要为大家展示了“ES6中javascript如何实现异步操作”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“ES6中javascript如何实现异步操作”这篇文章吧。具体如下:异步编程对
    阅读数:325 es6 javascript
  • ES6 javascript中class类的get与set怎么用

    这篇文章将为大家详细讲解有关ES6 javascript中class类的get与set怎么用,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。具体如下:与 ES5 一样, 在 Class 内部可以使用get和
    阅读数:497 es6 class javascript