Javascript闭包与作用域
1.Javascript的作用域是函数作用域而非块级作用域
|
1
2
3
4
5
6
7
8
9
10
11
12
|
//C语言#include <stdio.h>void main(){ int i=2; i--; if(i) { int j=3; } printf("%d/n",j); //use an undefined variable:j} |
这是因为c中的作用域是块级的,j是在if后的{ }中定义的,所以无法访问,然而在js中会是什么情况?
|
1
2
3
4
5
6
7
|
(function(){ var i=1; if(i==1){ var j=3; } console.log(j); //3 })() |
在这里,j是可以访问的,也就是说在一个函数中的任何位置定义的变量在该函数中的任何地方都是可见的
这里提及一句Javascript的作用域链(scope chain),每个函数定义时都会将他的作用域链定设为他定义的环境
|
1
2
3
4
5
|
function a(){ function b(){ //code }} |
这段代码中,b的环境为a,a的环境为全局(window),在b中查找变量时会先搜索自身函数内部,如果不存在就去a的内部查找,还不存在就去全局中查找,若还是找不到就是undefined,这就构成一条链
2.Javascript中变量的作用域分为全局变量和局部变量
在函数内部可以访问全局变量和函数内的局部变量,而在函数外部访问不到函数内的变量,看代码
|
1
2
3
4
5
|
var p=11;function f1(){ console.log(p);}f1(); //11 |
|
1
2
3
4
5
|
function f1(){ var p=11;}f1();console.log(p); //ReferenceError: p is not defined |
通过这俩段代码可以理解全局变量和局部变量,但是定义局部变量时一定要注意加上var,如果不加上其实定义的是一个全局变量,看代码
|
1
2
3
4
5
|
function f1(){ p=11;}f1();console.log(p); //11 |
3.那如何访问函数内部的变量并对它进行操作呢?这里就需要用到闭包
先看看闭包的官方解释:闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分
看到这句户我不禁想问,这是个啥?
后来参考了一些博客和《Javascript秘密花园》才开始理解,闭包大概就是函数内部的一个函数被外部调用,这样就可以调用内部变量了,比如下面这段
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
function f1(){ var p=11; return { increment: function() { p++; }, show: function() { alert(p) } }}var f=f1();f.show(); //11f.increment();f.show(); //12 |
先看一下控制台,f是什么样的

这里可以看到,f包含increment和show两个函数,而这两个函数是f1的内部函数所以可以访问p这个变量,在我理解,这里的increment和show就是f1()的两个闭包,用他们就可以从外部调用这个变量
4.闭包可以做些什么?
首先我觉得可以模拟private,就像上面那段代码,这个变量只能在这个函数内部访问,也只有使用了闭包才能访问
第二,和Javascript的垃圾回收有关,这里我还不是很清楚,等到搞明白了再来补上
5.这里有一个要注意的就是循环中使用闭包的问题,这里借用《Javascript秘密花园》里的一个例子
|
1
2
3
4
5
6
7
8
|
function f1(){ for(var i = 0; i < 10; i++) { setTimeout(function() { console.log(i); }, 1000); }}f1(); |
这段代码输出的是10个10而不是期望的0到9,因为闭包内是对i的引用,然后函数执行时i已经变成了10,这里可以使用自执行的匿名函数
|
1
2
3
4
5
6
7
8
9
10
11
|
function f1(){ for(var i = 0; i < 10; i++) { (function(e) { setTimeout(function() { console.log(e); }, 1000); })(i); }}f1(); |
这里的匿名函数将i作为参数,这里的e会有i的一个拷贝,而引用时是对e的引用,这就避免了上述的问题
Javascript闭包与作用域的更多相关文章
- javascript闭包和作用域链
最近在学习前端知识,看到javascript闭包这里总是云里雾里.于是翻阅了好多资料记录下来本人对闭包的理解. 首先,什么是闭包?看了各位大牛的定义和描述各式各样,我个人认为最容易一种说法: 外部函数 ...
- JS JavaScript闭包和作用域
JavaScript高级程序设计中对闭包的定义:闭包是指有权访问另外一个函数作用域中变量的函数. 从概念上,闭包有两个特点: 1.函数 2.能访问另外一个函数的作用域中的变量 在ES6之前,JavaS ...
- Javascript——闭包、作用域链
1.闭包:是指有权访问另一个函数作用域中的变量的函数.创建闭包的常见方式:在一个函数内部创建另一个函数. function f(name){ return function(object){ var ...
- Javascript闭包与作用域this
闭包与this的一般用法 关于js函数与闭包的文章想必大家都是在熟悉不过的了,作为js核心亦即最强大的功能之一,每次回过头翻出来看一看,都会有不一样的收获与理解,经典的含义无非如此而已. 1.闭包 1 ...
- Javascript中闭包的作用域链
作用域定义了在当前上下文中能够被访问到的成员,在Javascript中分为全局作用域和函数作用域,通过函数嵌套可以实现嵌套作用域. 闭包一般发生在嵌套作用域中.闭包是JavaScript最强大的特性之 ...
- 读书时间《JavaScript高级程序设计》三:函数,闭包,作用域
上一次看了第6章,面向对象.这里接着看第7章. 第7章:函数表达式 定义函数有两种方式:函数声明.函数表达式 //函数声明 function functionName(arg0,arg1,arg2){ ...
- javascript(面向对象,作用域,闭包,设计模式等)
javascript(面向对象,作用域,闭包,设计模式等) 1. 常用js类定义的方法有哪些? 参考答案:主要有构造函数原型和对象创建两种方法.原型法是通用老方法,对象创建是ES5推荐使用的方法.目前 ...
- javascript中闭包与作用域的理解
很多js的框架与插件编写都用到了闭包,所以,阅读和掌握闭包很有必要.最近学习vue框架时,经常会猜想很多功能的native js实现,很多都应用到了闭包,闭包除了目前已知的一些特性,如:可以保持局部变 ...
- javascript深入理解--作用域,作用域链,闭包的面试题解
一.概要 作用域和作用域链是js中非常重要的特性,关系到理解整个js体系,闭包是对作用域的延伸,其他语言也有闭包的特性. 那什么是作用域?作用域指的是一个变量和函数的作用范围. 1.js中函数内声明的 ...
随机推荐
- 嵌入式C语言优化小技巧
嵌入式C语言优化小技巧 1 概述 嵌入式系统是指完成一种或几种特定功能的计算机系统,具有自动化程度高,响应速度快等优点,目前已广泛应用于消费电子,工业控制等领域.嵌入式系统受其使用的硬件以及运行环境的 ...
- 常用的Linux操作二
1.sudo 说明:以系统管理者的身份执行指令,也就是说,经由 sudo 所执行的指令就好像是 root 亲自执行 . 2.who 说明 : 显示系统中有那些使用者正在上面,显示的资料包含 ...
- JavaBean的boolean isXXX反序列化问题
JavaBean规范中规定boolean的getter/setter 为isXXX/setXXX,包装类Boolean的getter/setter 为getXXX/setXXX,其中XXX为变量名(I ...
- opencv2对读书笔记——使用均值漂移算法查找物体
一些小概念 1.反投影直方图的结果是一个概率映射,体现了已知图像内容出如今图像中特定位置的概率. 2.概率映射能够找到最初的位置,从最初的位置開始而且迭代移动,便能够找到精确的位置,这就是均值漂移算法 ...
- Linux TCP队列相关参数的总结
作者:阿里技术保障锋寒 原文:https://yq.aliyun.com/articles/4252 摘要: 本文尝试总结TCP队列缓冲相关的内核参数,从协议栈的角度梳理它们,希望可以更容易的理解和记 ...
- android基础篇学习心得
android技术中,线程.进程.JNI.IPC和各个小框架结构是基本功.在跟随高焕堂老师的android程序猿到架构师之路系列视频中 学习完基础篇之后,颇有些心得,记录下来. android开发就是 ...
- COGS 渡轮问题 (LIS规定字典序输出方案数)
/* 下标字典序最小 */ #include<iostream> #include<cstdio> #include<cstring> #define maxn 1 ...
- 初识html、css时随笔记录
css部分样式 圆框效果:border-radius:5px; 固定样式:position:fixed;悬浮窗在IE6中position:absolute其余浏览器可以用fixed: 使table中的 ...
- (转)JavaWeb学习总结(十三)——使用Session防止表单重复提交
如何防止表单重复提交 在平时开发中,如果网速比较慢的情况下,用户提交表单后,发现服务器半天都没有响应,那么用户可能会以为是自己没有提交表单,就会再点击提交按钮重复提交表单,我们在开发中必须防止表单重复 ...
- MemCache缓存和C#自带的Cache缓存
1.MemCache: //初始化 static SockIOPool _pool; // 创建Memcached private static MemcachedClient Create(stri ...