Javascript中的作用域与闭包

薪资倒挂
• 阅读 1687

什么是作用域?
在当前运行环境下,可以访问的变量或函数的范围。
作用域分为词法作用域动态作用域
词法作用域是在js代码编译阶段就确定下来的; 对应的,witheval语句会产生动态作用域。

会产生新的作用域的情况:

  • 函数
  • {}(ES6)
  • eval

举个例子说明作用域

var a = 'hello';
function f1(){
    var a = 1;
    console.log(a);
}
f1();  // 1
console.log(a); // hello

可以看到f1中的变量a只能在f1中有效,f1外部访问不到里面的a;所以在f1中的a,其作用域就只限定在f1中。

再来个新概念:作用域链

var a = 'hello';
function f1(){
    console.log(a);// ps: f1中并未声明a
}
f1(); // hello

之所以输出hello, 是因为在f1中并未找到a的定义,此时程序并不会急于抛异常,而是会向调用f1的上一层寻找a的定义。如果没有,会继续再往上一层的上一层寻找,直到最顶层。
这样就形成了一个链式的作用域。

什么是闭包?

通常来讲,函数可以访问函数外面的变量;但是在函数外部,访问不到在函数里面定义的变量。

function f1(){
    var a = 1;
}
console.log(a);  // Uncaught ReferenceError: a is not defined

那么有没有可能访问到f1中的a呢?当然是有的, 看例子:

function f1(){
    var a = 1;
    function f2(){
        return a;
    }
    return f2;
}
var getA = f1();
console.log(getA()); // 1

我们在f1中,添加了一个函数f2(实际上f2就可以看做一个闭包)。
一般情况下,当函数执行完毕时,里面的变量会被自动销毁。但是因为我们把f2赋值给了外部的getA,所以f2不会被内存释放,同理f2中使用的a在f2的作用域中,也不会被释放,所以这个时候就可以访问到a。
而getA能够访问到a,这个在js的编译阶段就已经定型了(词法作用域)。

官方”的解释是:闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。
相信很少有人能直接看懂这句话,因为他描述的太学术。其实这句话通俗的来说就是:闭包就是能够读取其他函数内部变量的函数。

闭包的特点
闭包可以在函数外部改变函数中的变量的值,如果你把函数作为对象、闭包作为方法、局部变量作为私有属性使用,则会改变该变量的值;闭包还会把函数中的变量的值存储于内存中,对内存消耗很大,所以滥用闭包的结果就是影响网页性能,IE中则可能导致内存泄露

点赞
收藏
评论区
推荐文章
Dax Dax
4年前
JS核心原理理解闭包
前置概念在正式看闭包之前,我们先来学习一下前置知识,那就是JS中的作用域,我们知道,在ES5之中,作用域分为两种:全局作用域和函数作用域,随着ES6的到来,新增了块级作用域,想更好的理解闭包,那么搞清楚作用域是首要条件全局作用域我们知道,对于变量而言,我们一般会分成两类:全局变量和局部变量,一般定义在最外围环境的为全局变量,定义在函数当中的为局部变量,在we
Souleigh ✨ Souleigh ✨
4年前
JS - 作用域
一、作用域作用域,即变量(变量作用域又称上下文)和函数生效(能被访问)的区域或集合换句话说,作用域决定了代码区块中变量和其他资源的可见性举个例子function myFunction(){    let inVariable  "函数内部变量";}myFunction();//要先执行这个函数,否则根本不知
Symbol卢 Symbol卢
4年前
秒懂js作用域与作用域链
JavaScript中有一个被称为作用域(Scope)的特性。虽然对于许多新手开发者来说,作用域的概念并不是很容易理解,本文我会尽我所能用最简单的方式来解释作用域和作用域链,希望大家有所收获!好了下面开始我们的正文作用域常见的解释(什么是作用域)1.一段程序代码中所用到的名字并不总是有效,而限定它的可用性的范围就是这个名字的作用域;2.作用域规定了
Karen110 Karen110
3年前
一篇文章带你了解JavaScript作用域
在JavaScript中,对象和函数也是变量。在JavaScript中,作用域是你可以访问的变量、对象和函数的集合。JavaScript有函数作用域:这个作用域在函数内变化。一、本地JavaScript变量一个变量声明在JavaScript函数内部,成为函数的局部变量。局部变量有局部作用域:它们只能在函数中访问。JS://codeherecann
菜园前端 菜园前端
2年前
为你解惑JS作用域和作用域链知识
原文链接:变量作用域一个变量的作用域(scope)是程序源代码中定义这个变量的区域。全局变量拥有全局作用域,在JavaScript代码中的任何地方都是可以访问的。然而在函数内声明的变量只能在函数体内访问,它们是局部变量,作用域是局部性的。函数参数也是局部变
Jacquelyn38 Jacquelyn38
4年前
你所知道的JS变量作用域
变量的作用域,指的是变量在脚本代码中的可读、可写的有效范围,也就是脚本代码中可以使用这个变量的区域。在ES6之前,变量的作用域主要分为全局作用域、局部作用域(也称函数作用域)两种;在ES6及其之后,变量的作用域主要分为全局作用域、局部作用域、块级作用域这3种。相应作用域变量分别称为全局变量、局部变量、块级变量。全局变量声明在所有函数之外;局部变量是在函数体内
Stella981 Stella981
3年前
JavaScript易错知识点整理
前言本文是我学习JavaScript过程中收集与整理的一些易错知识点,将分别从变量作用域,类型比较,this指向,函数参数,闭包问题及对象拷贝与赋值这6个方面进行由浅入深的介绍和讲解,其中也涉及了一些ES6的知识点。JavaScript知识点1.变量作用域vara1;functio
Wesley13 Wesley13
3年前
JAVA记录
singleton作用域:当把一个Bean定义设置为singleton作用域是,SpringIoC容器中只会存在一个共享的Bean实例,并且所有对Bean的请求,只要id与该Bean定义相匹配,则只会返回该Bean的同一实例。值得强调的是singleton作用域是Spring中的缺省作用域。prototype作用域:protot
Stella981 Stella981
3年前
Python的四种作用域及调用顺序
↑关注星标 ~从此不迷路,后台回复【礼包】送你Python自学资料作用域又可以被称为命名空间,指变量起作用的范围。Python变量作用域可以分为四种,分别为局部作用域、嵌套作用域、全局作用域、内置作用域。作用域英文简写局部作用域LocalL嵌套作用域EnclosedE全局作用域Global
Wesley13 Wesley13
3年前
JS作用域和变量提升看这一篇就够了
作用域是JS中一个很基础但是很重要的概念,面试中也经常出现,本文会详细深入的讲解这个概念及其他相关的概念,包括声明提升,块级作用域,作用域链及作用域链延长等问题。什么是作用域第一个问题就是我们要弄清楚什么是作用域,这不是JS独有的概念,而是编程领域中通用的一个概念。我们以下面这个语句为例:letx1;这
Wesley13 Wesley13
3年前
Java连载7
一、变量1.注意点:在同一个“作用域”中,变量名不能重名,但是变量可以重新赋值。2.什么是作用域?答:描述的是变量的有效范围,在范围之内是可以被访问的,只要出了作用域就无法访问(也就是在大括号里面才行)3.关于变量的分类(1)局部变量:在方法体中声明的变量;(2)成员变量:在方法体外声明的变量。4.在不同的作用域中,变量名是可
薪资倒挂
薪资倒挂
Lv1
向前看的每一处风景,都是生死离别的倒计时。
文章
2
粉丝
0
获赞
0