函数中的作用域

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

     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. HTML解析组件HtmlAgilityPack使用

    HtmlAgilityPack是一个开源的解析HTML元素的类库,最大的特点是可以通过XPath来解析HMTL,如果您以前用C#操作过XML,那么使用起HtmlAgilityPack也会得心应手.目前 ...

  2. Revit中绘制带坡度管道

    激活管道绘制命令出现绘制管道上下文菜单,可以根据需要设置管道坡度值,是向上坡度还是向下坡度,其中两个命令非常有用,一个是继承高程,一个是忽略坡度以连接.在Revit建模中尝尝碰到一些带有坡度的管道,比 ...

  3. SoapUI Pro Project Solution Collection-DataSource(jdbc,excel)

    here give a solution for excel file change the excel configuration these: Set Excel file path in cur ...

  4. 利用Mahout实现在Hadoop上运行K-Means算法

    利用Mahout实现在Hadoop上运行K-Means算法 一.介绍Mahout Mahout是Apache下的开源机器学习软件包,目前实现的机器学习算法主要包含有协同过滤/推荐引擎,聚类和分类三个部 ...

  5. Linux2.6 内核的 Initrd 机制解析(转)

    from: https://www.ibm.com/developerworks/cn/linux/l-k26initrd/ 简介: Linux 的 initrd 技术是一个非常普遍使用的机制,lin ...

  6. 【LeetCode】268. Missing Number

    Missing Number Given an array containing n distinct numbers taken from 0, 1, 2, ..., n, find the one ...

  7. 解决cxf+spring发布的webservice,types,portType和message以import方式导入

    用cxf+spring发布了webservice,发现生成的wsdl的types,message和portType都以import的方式导入的.. 原因:命名空间问题 我想要生成的wsdl在同个文件中 ...

  8. Webstorm 11 注册/破解方法

    激活时选择第二个,也就是License server在下面输入框中填http://idea.lanyus.com就行了

  9. SQLite 入门教程 (终端)命令

    一.基本简介 SQLite 是一个自持的(self-contained).无服务器的.零配置的.事务型的关系型数据库引擎.因为他很小,所以也可以作为嵌入式数据库内建在你的应用程序中.SQLite 被应 ...

  10. Java NIO原理分析

    Java IO 在Client/Server模型中,Server往往需要同时处理大量来自Client的访问请求,因此Server端需采用支持高并发访问的架构.一种简单而又直接的解决方案是“one-th ...