函数中的作用域

所谓函数作用域,就是属于这个函数的全部变量都可以在整个函数的范围内使用及复用。

     function foo(a) {
         var b=a;
         function bar(c){
             var c=b*2;
             console.log(c);
         }
         bar();
     }
     foo(3);
     function foo(a) {
         var b=a;
         function bar(c){
             var c=b*2;
             console.log(c);
         }
         bar();
     }
     bar(2);  //not defined

命名冲突

在同一作用域中,相同的命名会引起冲突。

     function foo() {
         function bar(a){
             i=3;
             console.log(i+a);
         }
         for(var i=0;i<10;i++){
             bar(i);
         }
     }
     foo();

上面的代码将会引起冲突,函数会一直执行下去,行成死循环。

如何避免命名冲突呢?

(1)全局命名空间

一些第三方库通常都是在全局对象中声明一个独特的对象,库的方法和实例都在这个对象中,当我们调用时直接调用这个独特的对象就好了。

     var MyLibrary={
         param1:'param1',
         doSomething:function () {

         },
         doElseThing:function () {

         }
         //.......
     }

(2)模块管理

另一种避免冲突的方法和现在的模块机制很接近,就是从众多模块管理器中挑选一个来使用。使用这些工具,任何库都无需将标识符加入到全局作用域中,而是通过依赖管理器的机制将库的标识符显示地导入到另一个特定的作用域中

立执行函数

将函数包裹在一对括号中,使之成为一个表达式,再在后面加一个括号,使之执行,这样函数就会自执行。这种模式又称IIFE。

自执行函数有两种写法形式,第一种是将整个函数写在括号中,再在括号外面加一对括号:(function(){//do something})();

还有一种是:(function(){//do something}())。

这两种写法功能都相同。

自执行函数传参

     (function(doc){
         var a='按钮';
         doc.getElementById('btn').innerText=a;
     })(document);

块作用域

当我们写for循环时,我们都希望i只在循环的上下文中起到作用,而事实上i会被绑定到他所在的作用域中。比如上面的命名冲突中的例子。

那么如何解决块作用域的问题呢?

(1)使用自执行函数将循环包住,设置私有作用域。

     function foo(a) {
         function bar(a){
             i=3;
             console.log(a+i);
         }
         (function(){
             for(var i=0;i<10;i++){
                 bar(i);
             }
         })();
     }
     foo(3); //3 4 5 6 7 8 9 10 11 12

(2)使用es6中的let
let关键字为其声明的变量隐式地劫持了所在的作用域,上述例子可以改成:

     function foo(a) {
         function bar(a){
             i=3;
             console.log(a+i);
         }
         for(let i=0;i<10;i++){
             bar(i);
         }
     }
     foo(3); //3 4 5 6 7 8 9 10 11 12

(3)es6中const也会创建块级作用域。
const可以创建块级作用域,但是他表示常量。修改const创建的变量的值会报错。

     var foo=true;

     if(foo){
         var a=2;
         const b=3;

         a=3;//正常
         b=4;//错误
     }

     console.log(a);
     console.log(b); //b is not defined

《你不知道的javascript》一、函数作用域和块作用域的更多相关文章

  1. Javascript中的词法作用域、动态作用域、函数作用域和块作用域(四)

    一.js中的词法作用域和动态作用域      词法作用域也就是在词法阶段定义的作用域,也就是说词法作用域在代码书写时就已经确定了.       js中其实只有词法作用域,并没有动态作用域,this的执 ...

  2. 《你不知道的JavaScript》整理(一)——作用域、提升与闭包

    最近在读一本进阶的JavaScript的书<你不知道的JavaScript(上卷)>,里面分析了很多基础性的概念. 可以更全面深入的理解JavaScript深层面的知识点. 一.函数作用域 ...

  3. 你不知道的Javascript(上卷)读书笔记之三 ---- 函数作用域与块作用域

    1. 函数中的作用域 函数作用域的含义是指属于这个函数的全部变量都可以在整个函数范围内使用以及复用 2. 隐藏内部实现 函数经常使用于隐藏”内部实现”,可以把变量和函数包裹在一个函数的作用域中,然后用 ...

  4. 读书笔记-你不知道的JS上-函数作用域与块作用域

    函数作用域 Javascript具有基于函数的作用域,每声明一个函数,都会产生一个对应的作用域. //全局作用域包含f1 function f1(a) { var b = 1; //f1作用域包含a, ...

  5. 《你不知道的JavaScript(上)》笔记——作用域闭包

    当函数可以记住并访问所在的词法作用域时, 就产生了闭包, 即使函数是在当前词法作用域之外执行. function wait(message) { setTimeout( function timer( ...

  6. 《你不知道的JavaScript(上)》笔记——函数作用域和块作用域

    关于函数声明:如果 function 是声明中的第一个词, 那么就是一个函数声明, 否则就是一个函数表达式.例如匿名函数这种形式,函数会被当作函数表达式而不是一个标准的函数声明来处理. (functi ...

  7. 《你不知道的JavaScript(上)》笔记——作用域是什么

    Javascript是一门编译语言,它不是提前编译的, 编译结果也不能在分布式系统中进行移植. 在传统编译语言的流程中, 程序中的一段源代码在执行之前会经历三个步骤, 统称为"编译" ...

  8. ES6 学习笔记之二 块作用域与闭包

    "闭包是函数和声明该函数的词法环境的组合." 这是MDN上对闭包的定义. <JavaScript高级程序设计>中则是这样定义的:闭包是指有权访问另一个函数作用域中的变量 ...

  9. JavaScript词法作用域—你不知道的JavaScript上卷读书笔记(一)

    前段时间在每天往返的地铁上抽空将 <你不知道的JavaScript(上卷)>读了一遍,这本书很多部分写的很是精妙,对于接触前端时间不太久的人来说,就好像是叩开了JavaScript的另一扇 ...

随机推荐

  1. 微博mini for Windows Phone

    下载地址: http://vdisk.weibo.com/s/KrzW5

  2. LPC43xx SGPIO DMA and Interrupts

    The SGPIO output pins SGPIO14 and SGPIO15 can trigger a GPDMA request SGPIO pins SGPIO14 and SGPIO15 ...

  3. Oracle中的索引详解

    Oracle中的索引概述 索引与表一样,也属于段(segment)的一种.里面存放了用户的数据,跟表一样需要占用磁盘空间.索引是一种允许直接访问数据表中某一数据行的树型结构,为了提高查询效率而引入,是 ...

  4. IOS图像拉伸解决方案

    UIButton实现背景拉伸,即图片两端不拉伸中间拉伸的办法有如下两种: 第一种方法很简单而且使用性更广.做法就是直接拉伸想要setBackgroundImage的image,代码如下: UIImag ...

  5. Microsoft.Web.RedisSessionStateProvider 运行异常问题

    System.TimeoutException: Timeout performing GET MyKey, inst: 2, mgr: Inactive,  queue: 6, qu: 0, qs: ...

  6. 迁移SQL SERVER 数据库实例

    由于某些原因,需要将2个数据库实例合并为1个,也就是说要把其中的一台迁移到另外一台上面. 背景介绍 :下面的B,C代表2个实例,要把B中相关东西迁移到C实例上面.其中B上面有一部分的同步是从另外一台服 ...

  7. Flink 案例整合

    1.概述 Flink 1.1.0 版本已经在官方发布了,官方博客于 2016-08-08 更新了 Flink 1.1.0 的变动.在这 Flink 版本的发布,添加了 SQL 语法这一特性.这对于业务 ...

  8. 【Cocos2d-Js基础教学(6)网络层(弱联网)的封装及使用】

    谈到联网,在游戏中也是非常核心的模块,在官方Js-test中我们可以找到联网部分 的NetworkTest文件下有两个类 SocketIOTest.js(Socket 类) WebSocketTest ...

  9. cocos2dx在ubuntu下配置声音引擎

    声音引擎库和cocos2dx的库是分开的我们要使用的时候不得不重新修改一下makefile,首先我们要找到声音引擎库的位置,在cocos2dx的 根目录下有一个lib文件,看一下是否存在libcoco ...

  10. 通过DOS、SHELL批处理命令加载Lib并编译和打包Java项目(或者运行项目)

    有些时候,需要通过DOS批处理来编译整个项目的JAVA文件:并且编译后还要对Class文件进行打包成jar文件...这还不是最烦的,最烦的是,编译和打包的时候需要依赖其他多个jar文件,困难就这么来了 ...