作用域&&闭包
在了解闭包之前,先了解作用域
一,作用域
简单来说就是变量和函数可以访问的范围,在es5中变量作用域一般分为全局作用域和局部作用域,这个主要依据是全局变量还是局部变量
情景1:
<script>
var global = 'global'
function test () {
var local = 'local'
console.log(global)
}
test() // 返回global
console.log (local) // 报错:Uncaught ReferenceError
</script>
此处的global就是全局变量,在整个代码内都可以访问到这个变量;变量local就是局部变量,只在函数local内部能访问到,在外部无法访问
情景2:
<script>
var global = 'global'
function test () {
local = 'local'
}
test()
console.log(local) // 返回 local
</script>
此处的global和local都是全局变量,在整个代码内都可以访问到这两个变量
情景1和情景2的对比分析:
因为JavaScript作为一门弱类型语言,声明一个变量只需要var一个保留字,如果在函数中不使用var声明变量,该变量将提升为全局变量,这就是为什么情景2中返回的值是local
二,作用域链
JavaScript里面采用的是函数作用域,每一个函数都有一个作用域,也算是一条独立的作用域链。比较典型的就是函数里面嵌套函数
<script>
var result = 'global'
function test () {
var result = 'local'
function inner () {
console.log(result) // 返回local
}
inner()
}
test ()
console.log(result) // 返回global
</script>
以上三段作用域构成作用域链,作用域链的查找顺序:inner本函数-->上一层test函数-->window全局对象,当调用内部的inner方法的时候,里面没有声明变量result,但是可以访问外部函数test的变量,如果外部函数依然没有这个变量,就继续查找全局变量,直到找不到为止,如果找不到的话,就抛出 ReferenceError 错误。通过作用域链,子函数可以访问父函数的变量,但是父函数无法访问子函数里面的变量,闭包就可以解决这个问题。
三,闭包
简单的理解就是有权访问另一个函数作用域中的变量的函数。
闭包理解的误区:
<script>
function test() {
var result = 'local'
return result
}
var res = test()
console.log(res)
</script>
上面的这个是闭包函数么?答案显示是no!以上的函数确实是实现了外部可以访问函数内部的变量result,但是当函数调用完成之后,里面的变量result也就用完了被销毁了,即函数内的局部变量的生命周期仅存在于函数的声明周期内,函数被销毁,函数内的变量也自动被销毁,所以这个函数不是闭包函数
闭包函数的正解,如下:
<script>
function test () {
var result = 'local'
function inner () {
return result
}
return inner
}
var res = test()
console.log(res()) // 返回local
</script>
上面的这段代码不仅实现了外部可以访问函数test内的变量result,同时当函数调用完的时候,通过闭包引用的外层作用域内的变量依然存在,并且将一直存在,直到执行的闭包作用域被销毁
四,闭包的特点
1,可以读取函数内部的局部变量
2,局部变量的值可以存在内存中,可以反复使用,并且不存在全局变量的污染问题
3,占用更多的内存,不容易被释放
应用场景如下:
<script>
function count() {
var num = 0
function inner () {
return num+=1
}
return inner
}
var result = count()
console.log(result()) // 返回1
</script>
作用域&&闭包的更多相关文章
- JavaScript作用域闭包简述
JavaScript作用域闭包简述 作用域 技术一般水平有限,有什么错的地方,望大家指正. 作用域就是变量起作用的范围.作用域包括全局作用域,函数作用域以块级作用域,ES6中的let和const可以形 ...
- 读《你不知道的JavaScript(上卷)》后感-作用域闭包(二)
github原文 一. 序言 最近我在读一本书:<你不知道的JavaScript>,这书分为上中卷,内容非常丰富,认真细读,能学到非常多JavaScript的知识点,希望广大的前端同胞们, ...
- 你不知道的JS之作用域和闭包(五)作用域闭包
原文:你不知道的js系列 一个简单粗暴的定义 闭包就是即使一个函数在它所在的词法作用域外部被执行,这个函数依然可以访问这个作用域. 比如: function foo() { var a = 2; fu ...
- 【Python 函数对象 命名空间与作用域 闭包函数 装饰器 迭代器 内置函数】
一.函数对象 函数(Function)作为程序语言中不可或缺的一部分,但函数作为第一类对象(First-Class Object)却是 Python 函数的一大特性. 那到底什么是第一类对象(Firs ...
- js 函数 作用域 全局作用域 局部作用域 闭包
一个变量没有声明但调用 直接报错,声明没有赋值会显示未定义. 作用域 作用域(scope):一条数据可以在哪个范围中使用. 通常来说,一段程序代码中所用到的数据并不总是有效/可用的,而限定这个数据的可 ...
- python基础(7)-函数&命名空间&作用域&闭包
函数 动态参数 *args def sum(*args): ''' 任何参数都会被args以元组的方式接收 ''' print(type(args)) # result:<class 'tupl ...
- Python记录9:函数4:名称空间作用域+闭包函数+装饰器
''' 一: 名称空间namespaces 名称空间就是存放名字与值绑定关系的内存空间 二: 名称空间分为三种 内置名称空间: 1. 特点: 存放是python解释器自 ...
- 函数嵌套>作用域>闭包函数
一:函数对象 函数是第一类对象,即表示函数可以当做数据传递 可以被引用:把函数内存地址赋值给一个变量名,仍然遵循函数的调用规则. 可以被当做参数传递:传递的是函数的运行的结果#可以当做返回值 把函数作 ...
- 10 - 函数嵌套-作用域-闭包-LEGB-函数销毁
目录 1 函数嵌套 2 作用域 2.1 global关键字 3 闭包 3.1 nonlocal关键字 4 默认值的作用域 5 变量名解析原则LEGB 6 函数的销毁 1 函数嵌套 一个 ...
随机推荐
- python__面向对象,继承,命名空间
http://www.cnblogs.com/Eva-J/articles/7293890.html 阅读目录 楔子 面向过程vs面向对象 初识面向对象 类的相关知识 对象的相关知识 对象之间的交互 ...
- Arch Linux安装后的一些初始设置简介
配置有线网络. 没网络的时候,可以直接设定ip应急,后面 netctl 才是正规设置: # ip addr add 192.168.0.100/24 dev enp0s4# ip link set d ...
- 【2.0】SpringBoot连接MySql 8.0的url设置
jdbc:mysql://localhost:3306/enterprise?useUnicode=true&&useSSL=false&&characte ...
- jsp/servlet学习一之servlet初窥
Java Servlet技术简称Servlet技术,是java开发web应用的底层技术.Servlet是一个java程序,一个servlet应用有一个或多个Servlet程序.jsp页面会被转换和编译 ...
- idea基于hibernate生成的Entitle对象,会忽略外键属性
需要自己手动添加 如 private String cgcode; @Basic @Column(name = "cgcode") public String getCgcode( ...
- U3D外包团队—技术分享 U3d中获得物体的size
以size的x方向为例 1:gameObject.renderer.bounds.size.x;//这个值的结果真实反应出有MeshRenderer这个组件的模型的尺寸.不需要再乘以localScal ...
- js中实现截取数组的后几个元素作为一个新数组的方法
有时候我们会遇到这种需求,截取数组中后5个元素作为一个新数组,且顺序不能变.数组中的slice()方法和splice()方法都可以实现这样的操作. const arr = [1,2,7,2,6,0,3 ...
- java笔记 -- java数据类型与类型转换
Java是一种强类型语言, 这就意味着必须为每一个变量声明一种类型. Java中一共有8中基本类型: 4种整型: 整型: 用于表示没有小数部分的数值, 允许为负数 类型 存储需求 取值范围 int: ...
- eclipse添加js智能代码提示
安装重启之后,在项目名上右键 结束
- RabittMQ安装和Erlang安装教程
安装Erlang 官方安装地址文档: http://www.rabbitmq.com/install-rpm.html 根据官网的推荐 进入到专为RabbitMQ整理的极简版Erlang https: ...