在JavaScript中,作用域是执行代码的上下文。作用域有3种类型:

1.全局作用域

2.局部作用域---(又叫函数作用域)

3.eval作用域

var foo =0;//全局作用域

console.log(foo);//输出 0
var myFunction =function(){
  var foo =1;//局部作用域
  console.log(foo);//输出 1
  
  var myinnerFunction =function(){
    var foo =2;//局部作用域
    console.log(foo);//输出 2
  }();
}();
eval('var foo = 3; console.log(foo);');//eval()作用域

在函数内部使用var定义的代码,其作用域是局部的,且只对该函数的其他表达式是可见的,包括嵌套/子函数中的代码。

var a = "Hello";//
(function b() {//只执行函数b()
alert(a); //undefined
var a = "World";
alert(a);
})()
alert(a); //Hello

JavaScript没有块作用域

JavaScript中if(){}、for无法创建作用域

var foo=1;//foo等于1
if(true){
foo =2;//foo等于2
for (var i=3;i<=5;i++){
foo=i;
console.log("nei:"+foo)
} }
console.log("wai:"+foo)
结果:
//nei:3
//nei:4
//nei:5
//wai:5

if条件里面与for循环之后内部的结果在下面console.log("wai:"+foo)打印出来的结果是5,说明JavaScript没有块级作用域,只有函数作用域与全局作用域与eval作用域。

其他语言里面的块级作用域:由花括号封闭的代码块都有自己的作用域,也就是块级作用域(私有作用域)-----花括号是他们作用域的边界,而js的块级作用域边界是function。详细介绍可参阅http://www.cnblogs.com/fengmiaosen/archive/2011/01/10/1932403.html

 js闭包

网上有很多种解说,其中有一种比较容易理解的说法:

js分全局作用域和函数作用域。函数作用域里可以访问到全局,通过一个叫作用域链的东西。但全局怎么访问函数呢?就有人想了在函数里面再写一个函数(闭包),这样把作用域链加长了。就可以在全局访问到函数里的数据了。闭包能访问到父级函数里面的数据说明父级里的数据一直存在内存中(闭包存在的情况下),这就会导致内存一直被占着

简而言之闭包就是能够读取其他函数内部变量的函数。

总结:闭包它的最大用处有两个,一个是可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。
var countFromZero =function(){
  var count =0;
  return function(){//调用countFromZero的时候返回嵌套的子函数
    return ++count ;//count的作用域链定义在父函数里
  }
}()
countFromZero()//输出1
countFromZero()//输出2
countFromZero()//输出3 变量的值始终保持在内存中不会被立即释放出来,每调用一次countFromZero(),count就会加1,而不是调用外出函数后count立刻被清除

注意:由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,必要的时候适当销毁

闭包 js回收机制

回收规则如下:

    1.全局变量不会被回收。

    2.局部变量会被回收,也就是函数一旦运行完以后,函数内部的东西都会被销毁。

     3.只要被另外一个作用域所引用就不会被回收

作用域名字解析顺序 

javascript中一个名字(name)以四种方式进入作用域(scope),其优先级顺序如下:
1、语言内置:所有的作用域中都有 this 和 arguments 关键字
2、形式参数:函数的参数在函数作用域中都是有效的
3、函数声明:形如function foo() {}
4、变量声明:形如var bar;

名字声明的优先级如上所示,也就是说如果一个变量的名字与函数的名字相同,那么函数的名字会覆盖变量的名字,无论其在代码中的顺序如何。但名字的初始化却是按其在代码中书写的顺序进行的,不受以上优先级的影响。看代码:

(function(){
var foo;
console.log(typeof foo); //function function foo(){} foo = "foo";
console.log(typeof foo); //string
})();

闭包参考链接

https://www.zhihu.com/question/34510484/answer/59303912

http://www.cnblogs.com/uedt/archive/2010/10/28/1863389.html

http://www.cnblogs.com/liyatang/archive/2011/08/05/2128102.html

JavaScript作用域和闭包的更多相关文章

  1. javascript作用域和闭包之我见

    javascript作用域和闭包之我见 看了<你不知道的JavaScript(上卷)>的第一部分--作用域和闭包,感受颇深,遂写一篇读书笔记加深印象.路过的大牛欢迎指点,对这方面不懂的同学 ...

  2. JavaScript 作用域和闭包——另一个角度:扩展你对作用域和闭包的认识【翻译+整理】

    原文地址 --这篇文章有点意思,可以扩展你对作用域和闭包的认识. 本文内容 背景 作用域 闭包 臭名昭著的循环问题 自调用函数(匿名函数) 其他 我认为,尝试向别人解释 JavaScript 作用域和 ...

  3. 举例详细说明javascript作用域、闭包原理以及性能问题(转)

    转自:http://www.cnblogs.com/mrsunny/archive/2011/11/03/2233978.html 这可能是每一个jser都曾经为之头疼的却又非常经典的问题,关系到内存 ...

  4. JavaScript 作用域和闭包

    作用域的嵌套将形成作用域链,函数的嵌套将形成闭包.闭包与作用域链是 JavaScript 区别于其它语言的重要特性之一. 作用域 JavaScript 中有两种作用域:函数作用域和全局作用域. 在一个 ...

  5. javascript作用域、闭包、对象与原型链

    原文作者总结得特别好,自己收藏一下.^-^ 1.作用域1.1函数作用域JS的在函数中定义的局部变量只对这个函数内部可见,称之谓函数作用域.它没有块级作用域(因此if.for等语句中的花括号不是独立作用 ...

  6. javascript作用域与闭包

    Javasript作用域概要 在javascript中,作用域是执行代码的上下文,作用域有三种类型: 1)  全局作用域 2)  局部作用域(函数作用域) 3)  eval作用域 var foo = ...

  7. JavaScript作用域与闭包总结

    1.全局作用域 所有浏览器都支持 window 对象,它表示浏览器窗口,JavaScript 全局对象.函数以及变量均自动成为 window 对象的成员.所以,全局变量是 window 对象的属性,全 ...

  8. javascript——作用域与闭包

    http://www.cnblogs.com/lucio-yr/p/4047972.html 一.作用域: 在函数内部:用 var 声明的表示局部变量,未用var的是全局变量. 作用域取决于变量定义时 ...

  9. 《JavaScript 闯关记》之作用域和闭包

    作用域和闭包是 JavaScript 最重要的概念之一,想要进一步学习 JavaScript,就必须理解 JavaScript 作用域和闭包的工作原理. 作用域 任何程序设计语言都有作用域的概念,简单 ...

随机推荐

  1. VB中复制-粘贴-剪切键实现

    If Me.ActiveControl.GetType.BaseType.ToString = "System.Windows.Forms.TextBoxBase" Then Wi ...

  2. Visual Studio 2013 智能提示

    Visual Studio 2013中,智能提示功能突然用不了,查了一下,使用命令行重置VS的方法解决了这个问题.步骤如下: 开始菜单 -->所有程序-->Visual Studio 20 ...

  3. 【目录】Qt

    Qt 自己生成ui加入工程 C++ GUI Qt4 学习笔记1 C++ GUI Qt4 学习笔记2 C++ GUI Qt4 学习笔记3 C++ GUI Qt4 学习笔记4 C++ GUI Qt4 学习 ...

  4. ORACLE用户创建&删除

    ●sqlplus登陆sqlplus sys/isc@testgmmc as sysdba●创建用户create user testpoi3 IDENTIFIED by iscaccount unloc ...

  5. Linux之CentOS 常用命令

    软件安装:安装软件:yum install <名称>移除软件:yum remove <名称>安装软件包:rpm -ivh <包全名>安装ifconfig: yum ...

  6. 数字转IP地址函数

    --------------------------------------------------------------------- -- Author : htl258(Tony) -- Da ...

  7. TodoMVC中的Backbone+MarionetteJS+RequireJS例子源码分析之三 Views

    这个版本的TodoMVC中的视图组织划分比较细,更加易于理解,这也得益于Marionette为我们带来了丰富的视图选择,原生的backbone只有views,而Marionette则有itemview ...

  8. tibble包:高效显示表格数据的结构

    1 tibble包简介 包名: tibble 编码: UTF- 最新版本: 1.2 标题: 简单数据框 描述: 构建一个 'tbl_df' 类,可以比传统的R数据框提供更好的检查和打印功能. 作者: ...

  9. javascript面向对象(三):非构造函数的继承

    本文来自阮一峰 这个系列的第一部分介绍了"封装",第二部分介绍了使用构造函数实现"继承". 今天是最后一个部分,介绍不使用构造函数实现"继承" ...

  10. 【最简单IOC容器实现】实现一个最简单的IOC容器

    前面DebugLZQ的两篇博文: 浅谈IOC--说清楚IOC是什么 IoC Container Benchmark - Performance comparison 在浅谈IOC--说清楚IOC是什么 ...