我认知的javascript之作用域和闭包
说到javascript,就不得不说javascript的作用域和闭包;当然,还是那句老话,javascript在网上都说得很透彻了,我也就不过多的强调了;
作用域:javascript并没有像其他的后台语言那样有块级作用域(es6推出了一些新的语法与特性,在这儿就不多说了,有兴趣的可以点这里),那么js的作用域有哪些呢?
1.全局作用域:全局作用域一般称之为window,无论什么地方(function),都能调用到window作用域上的东西;
2.局部作用于(function):前面说过,javascript在es6之前不存在块级(两个大括号之间)作作用域,那么,这儿说的局部作用于就是function内的作用域,也就是说,两个同级的function不能调用到对方内部定义的变量。
再说作用域之前,看下面一个例子(也算是作用域):
window.socpe= "window";//作用域A
(function(){//作用域B
var socpe = "function";
function Socpe(){//作用域C
var socpe = "Socpe";
console.log(socpe);//socpe = "Socpe";
}
Socpe();
console.log(socpe);//socpe = "function";
console.log(window.socpe);//socpe = "window";
})()
var socpe = "custom";
console.log(socpe);//socpe = "custom";
console.log(window.socpe);//socpe = "custom";
在上面的例子中可以看到,javascript在查找变量的时候,是返回找到的第一个,通过var可以重复定义(涉及到js的编译,后面说明),同级作用域下重复定义会导致重新赋值,子级作用域重新定义会在当前作用域覆盖并且不影响父级作用域;当然,这儿这是提醒大家有这么回事,但不建议大家这么操作;
特殊的东西说了,现在来说比较正常的:
window.socpe= "window";//作用域A
(function(){//作用域B
socpe = "function";
function Socpe(){//作用域C
socpe = "socpe";
console.log(socpe);//socpe = "socpe";
}
Socpe();
console.log(socpe);//socpe = "socpe";
console.log(window.socpe);//socpe = "socpe";
})()
console.log(socpe);//socpe = "socpe";
上面这个例子,就可以明显的看到,子级可以调用并改变父级作用域的变量;
闭包:闭包,在javascript中,非常的重要,了解了闭包,才能规避一些不必要的错误,写出更优雅的代码;在说闭包之前,先说说javascript的回收机制:在javascript也的垃圾回收是自动完成的,简单点就是:会找出不再使用的变量,然后释放掉其占用的内存,但是这个过程不是时时的,因为其开销比较大,所以垃圾回收器会按照固定的时间间隔周期性的执行。
var ClosureTest =(function(){
var a = 0;
return function(){
console.log(++a);
};
})()
ClosureTest();//
ClosureTest();//
ClosureTest();//
上面的例子,就是一个典型的闭包。下面我就来说一下不理解闭包而产生的错误结果:
var myArry = [],
i = 0,
j = 0;
for(i = 0; i < 9; i++) {
myArry[i] = function() {
console.log(i);
};
}
for(j = 0; j < 9; j++) {
myArry[j](); //
}
myArry = [];
for(i = 0; i < 9; i++) {
myArry[i] = (function(a) {
return function() {
console.log(a)
};
})(i);
}
for(j = 0; j < 9; j++) {
myArry[j](); // 1 - 9
}
上面的代码中,第一个循环看着的对的,也没有什么毛病,但是结果却并不是我们想要的;而第二个i循环,就用闭包知识,多余的我也就不多说了,可以考虑思考一下为什么第二个i循环就能得到我们想要的正确结果呢!
好了,闭包和作用域就说到这儿,由于水平有限,多多包涵,欢迎指出不正确的地方!
我认知的javascript之作用域和闭包的更多相关文章
- 剖析JavaScript函数作用域与闭包
在我们写代码写到一定阶段的时候,就会想深究一下js,javascript是一种弱类型的编程语言,而js中一个最为重要的概念就是执行环境,或者说作用域.作用域重要性体现在哪呢?首先,函数在执行时会创建作 ...
- 你不知道的JavaScript(作用域和闭包)
作用域和闭包 ・作用域 引擎:从头到尾负责整个JavaScript的编译及执行过程. 编译器:负责语法分析及代码生成等. 作用域:负责收集并维护由所有声明的标识符(变量)组成的一系列查询,并实施一套非 ...
- JavaScript 函数作用域和闭包
函数作用域和闭包 词法作用域 它们在定义它们的作用域里运行,而不是在执行的作用域运行,但是只有在运行时,作用域链中的属性才被 定义(调用对象),此时,可访问任何当前的绑定. 调用对象 ...
- JavaScript从作用域到闭包
目录 作用域 全局作用域和局部作用域 块作用域与函数作用域 作用域中的声明提前 作用域链 函数声明与赋值 声明式函数.赋值式函数与匿名函数 代码块 自执行函数 闭包 作用域(scope) 全局作用域 ...
- javascript的作用域和闭包(三)闭包与模块
一些很重要的说明:前面三篇博客详细的介绍了,引擎与编译器和作用域的关系,重点需要理解的是编译器中的分词与词法分析,JavaScript的特有的“赋值操作的左右侧”引用操作:编译阶段的词法作用域的工作原 ...
- JavaScript的作用域与闭包
JavaScript的作用域以函数为界,不同的函数拥有相对独立的作用域.函数内部可以声明和访问全局变量,也可以声明局部变量(使用var关键字,函数的参数也是局部变量),但函数外部无法访问内部的局部变量 ...
- JavaScript之作用域和闭包
一.作用域 作用域共有两种主要的工作模型:第一种是最为普遍的,被大多数编程语言所采用的词法作用域,另外一种叫作动态作用域: JavaScript所采用的作用域模式是词法作用域. 1.词法作用域 词法作 ...
- 前端知识体系:JavaScript基础-作用域和闭包-JavaScript的作用域和作用域链
JavaScript的作用域和作用域链 作用域: 变量的作用域无非两种:全局作用域和局部作用域 全局作用域: 最外层函数定义的变量拥有全局作用域.即对任何内部函数来说都是可以访问的. <scri ...
- Javascript的作用域和闭包(一)
一.作用域是什么? 几乎所有的编程语言最基本的功能之一,就是能够存储变量的值,并且能访问和修改这些值. 修改变量值的过程我们通常在程序执行时,称为改变一个对象的状态.有了状态,让程序变得有非常有趣. ...
随机推荐
- JVM基础系列第6讲:Java 虚拟机内存结构
看到这里,我相信大家对于一个 Java 源文件是如何变成字节码文件,以及字节码文件的含义已经非常清楚了.那么接下来就是让 Java 虚拟机运行字节码文件,从而得出我们最终想要的结果了.在这个过程中,J ...
- 说一说MVC的CSRF(三)
用途:防止CSRF(跨网站请求伪造). 用法:在View->Form表单中:<%:Html.AntiForgeryToken()%> 在Controller->Action动作 ...
- webpack 2 系列
webpack 2 系列 webpack 是一个强大的工具,学会通过工具来解决开发效率问题,是每一个 工程师都必备的技能之一. 那么我们来从零开始搭建一个 基于webpack 2 到 开发架子,来提升 ...
- spring-boot-2.0.3启动源码篇四 - run方法(三)之createApplicationContext
前言 此系列是针对springboot的启动,旨在于和大家一起来看看springboot启动的过程中到底做了一些什么事.如果大家对springboot的源码有所研究,可以挑些自己感兴趣或者对自己有帮助 ...
- InnoSetup 使用
目录 简介 示例脚本 相关参考 在进行 WPF 程序打包发布的时候如果对程序打包没有特别高的要求,InnoSetup 足以胜任普通的程序打包发布需求,它支持安装包加密,安装包升级安装,注册表操作等常规 ...
- c#源码的执行过程
我想也许要写些东西,记录我做程序员的日子吧 ================================================ 要讲到C#源码的执行过程 首先要提下程序集,因为Clr并不 ...
- aps.net core mvc中使用session
原因>>用session是想验证 前端输入的验证码和后端存入seesion的是否一致,也可以使用的是TempData[]. 铺垫>> 前端用GetValidateCode()方 ...
- 学JAVA第九天,for循环算质数及for遍历数组的方法。
昨天终于收到了评论,老开心了!!! 算质数之前是我最怕的一件事,以前上学不好好学,之前学C#的时候也没好好研究, 直到今天老师逼我要用JAVA算质数,硬着头皮琢磨老半天才琢磨透,现在看来也挺简单的. ...
- Hibernate框架笔记03表操作多对多配置
目录 1. 数据库表与表之间的关系 1.1 一对多关系 1.2 多对多关系 1.3 一对一关系[了解] 2. Hibernate的一对多关联映射 2.1 创建一个项目,引入相关jar包 2.2. 创建 ...
- 5-Redis 的持久化之 RDB
2016-12-22 13:58:48 该系列文章链接NoSQL 数据库简介Redis的安装及及一些杂项基础知识Redis 的常用五大数据类型(key,string,hash,list,set,zse ...