精华内容
下载资源
问答
  • 一、块级作用域的说明 在学习JavaScript的变量作用域之前,我们应当明确几点: a、JavaScript的变量作用域是基于其特有的作用域链的。 b、JavaScript没有块级作用域。 c、函数中声明的变量在整个函数中都有定义。  ...
  • 主要介绍了ES6使用let命令更简单的实现块级作用域,结合实例形式分析了ES6中let命令与var的区别及具体使用方法,需要的朋友可以参考下
  • 讲到这里,首先理解两个概念:块级作用域与函数作用域。 什么是块级作用域呢? 任何一对花括号({和})中的语句集都属于一个块,在这之中定义的所有变量在代码块外都是不可见的,我们称之为块级作用域。 函数作用...
  • 本文实例讲述了JavaScript使用闭包模仿块级作用域操作。分享给大家供大家参考,具体如下: 在阅读这篇文章之前,建议先阅读JavaScript的作用域链以及JavaScript闭包。 正如闭包的定义一样:“闭包指的是有权访问另一...
  • 在ES6之前,javascript只有全局作用域和函数作用域。所谓作用域就是一个变量定义并能够被访问到的范围。也就是说如果一个变量定义在全局(window)上,那么在任何地方都能访问到这个变量,如果这个变量定义在函数...
  • 由于es5没有像其它类C语言一样的块级作用域,因此es6增加了let定义变量,用来创建块级作用域。 我们来看一个var定义变量的示例: function setName(){ if(condition){ var name = 'loho'; console.log(name); }...
  • JavaScript 中没有块级作用域 可能会对这个问题大家可能有点不理解,先看个例子 var a = [] for(var i = 0; i < 10; i++){ a[i] = function(){ console.log(i); } } a[6](); 我想很多人会觉得这个问题的结果...
  • js代码-es5块级作用域实现
  • 在 Es6 之前有块之说,但没有块级作用域之说!!!如下: if (true) { var a = '1' } console.log(a) // 1 for (var i = 1; i < 3; i++) { // TODO } console.log(i) // 3 如上:一个{}即形成了一个块。但是...

    前言

    在 Es6 之前有块之说,但没有块级作用域之说!!!如下:

    if (true) {
      var a = '1'
    }
    console.log(a) // 1
    
    for (var i = 1; i < 3; i++) {
        // TODO
    }
    console.log(i)  // 3
    

    如上:一个{}即形成了一个块。但是没有作用域一说,故在外面也可以正常访问到var声明的变量 。

    我为什么说是 函数作用域(局部作用域) 而不是 局部作用域(函数作用域) 这样写,就是想特意说一下,在函数内部可以形成一个局部作用域!!!

    接下来以代码形式演示各个作用域:

    var a = 1
    console.log(a) // 1
    
    { 
       var a = 2
    }
    console.log(a) // 2
    
    function test() {
      var a = 3	   // 函数作用域(局部作用域),只在函数内部可以访问
    }
    test()
    console.log(a) // a is not defined
    
    function test() {
      a = 3		   // 在函数内部声明一个全局作用域,在外部也可以访问
    }
    test()
    console.log(a) // 3
    
    

    如上:在 全局 或 块 里面定义一个变量,或在 函数里面 定义一个不带var的变量即定义了一个全局作用域的变量。即也说明了在函数作用域内的变量,在外面不能访问到。

    事件点击循环

    var element = [{}, {}, {}]
    for (var i = 0; i < element.length; i++) {
      element[i].onclick = function () {
        console.log(i)   // 注意:此时的i是上层作用域值,故不属于函数作用域内的变量!!!
      }
    }
    element[1].onclick()  // 3   
    

    因为{}块没有作用域的概念,所以 i即是一个全局变量,而执行事件是在for循环之后执行的,此时i已经变为了3,所有引用i的地方都变为了3

    函数作用域的方式升级

    for (var i = 0; i < element.length; i++) {
      element[i].onclick = (function (i) { // 函数1
        // 每次循环相当于位置在函数1中定义了一个新的变量,此时为函数2拿的值为当前作用域的即传入的值
        return function () {  // 函数2
          console.log(i)
        }
      })(i)
    }
    element[1].onclick() // 1
    

    此时把onclick写成一个闭包的形式,然后传入把i传入,这样传入的i为函数1中的变量,而js中,只有在函数内部的函数才能读取局部变量,而函数2中所读取的i为函数1的局部变量。故在每次循环中,把i保存了下来。故每次i都不是3而是每次循环出来的传入的值。

    let升级

    for (let i = 0; i < element.length; i++) {
      element[i].onclick = function () {
        console.log(i)
      }
    }
    element[1].onclick()  // 1
    

    使用let升级后,块 有了 块级作用域的概念。在定义i的时候,每个{} 花括号内形成一个独立作用域,与闭包类似。

    提问:for循环是怎么形成块级作用域的

    for (let i = 0; i < 3; i++) {
      console.log(i);
    }
    console.log(i);   		// i is not defined。因为i在for形成的块级作用域内,故外部拿不到i
    
    // 实际执行如下:
    {						
        let i = 0    		// for循环的作用域
        if (i < 3) {
          console.log(i); 	// if判断里面的作用域,此时的i在一个新的{}块内部,有自己的独立块级作用域。而使用var定义变量的话{}不                         // 能形成块级作用域
        }
        i++
        
        // TODO...
    }
    

    由上可明确的展示 for 循环中,var 和 let 的区别。

    再来一问

    for (let i = 0; i < 3; i++) {
      let i = 'foo'
      console.log(i);  // foo
    }
    如上拆解循环
    {						
        let i = 0    		// for循环的作用域
        if (i < 3) {
          let i = 'foo'
          console.log(i); 	// 此时在新的跨级作用域内重新定义了 i。所以不会报错。
        }
        i++
        
        // TODO...
    }
    
    展开全文
  • 块级作用域

    千次阅读 2019-03-08 15:30:41
    首先,ECMAScript和JavaScript关系: ECMAScript是一个国际通过的标准化脚本语言。JavaScript由ECMAScript和DOM、BOM三者组成。...JS中作用域有:全局作用域、函数作用域。没有块作用域的概念。...

    首先,ECMAScript和JavaScript关系:
          ECMAScript是一个国际通过的标准化脚本语言。JavaScript由ECMAScript和DOM、BOM三者组成。可以简单理解为:ECMAScript是JavaScript的语言规范,JavaScript是ECMAScript的实现和扩展。
    1. 块作用域{ }

    JS中作用域有:全局作用域、函数作用域。没有块作用域的概念。ECMAScript 6(简称ES6)中新增了块级作用域。
    块作用域由 { } 包括,if语句和for语句里面的{ }也属于块作用域。

    <script type="text/javascript">
        {
            var a = 1;
            console.log(a); // 1
        }
        console.log(a); // 1
        // 可见,通过var定义的变量可以跨块作用域访问到。

        (function A() {
            var b = 2;
            console.log(b); // 2
        })();
        // console.log(b); // 报错,
        // 可见,通过var定义的变量不能跨函数作用域访问到

        if(true) {
            var c = 3;
        }
        console.log(c); // 3
        for(var i = 0; i < 4; i++) {
            var d = 5;
        };
        console.log(i);    // 4   (循环结束i已经是4,所以此处i为4)
        console.log(d); // 5
        // if语句和for语句中用var定义的变量可以在外面访问到,
        // 可见,if语句和for语句属于块作用域,不属于函数作用域。
    </script>

    2. var、let、const的区别

        var定义的变量,没有块的概念,可以跨块访问, 不能跨函数访问。
        let定义的变量,只能在块作用域里访问,不能跨块访问,也不能跨函数访问。
        const用来定义常量,使用时必须初始化(即必须赋值),只能在块作用域里访问,而且不能修改。

    <script type="text/javascript">
        // 块作用域
        {
            var a = 1;
            let b = 2;
            const c = 3;
            // c = 4; // 报错
            var aa;
            let bb;
            // const cc; // 报错
            console.log(a); // 1
            console.log(b); // 2
            console.log(c); // 3
            console.log(aa); // undefined
            console.log(bb); // undefined
        }
        console.log(a); // 1
        // console.log(b); // 报错
        // console.log(c); // 报错

        // 函数作用域
        (function A() {
            var d = 5;
            let e = 6;
            const f = 7;
            console.log(d); // 5
            console.log(e); // 6  (在同一个{ }中,也属于同一个块,可以正常访问到)
            console.log(f); // 7  (在同一个{ }中,也属于同一个块,可以正常访问到)

        })();
        // console.log(d); // 报错
        // console.log(e); // 报错
        // console.log(f); // 报错
    </script>

     

    • 允许在块级作用域内声明函数。
    • 函数声明类似于var,即会提升到全局作用域或函数作用域的头部。
    • 同时,函数声明还会提升到所在的块级作用域的头部。

    注意,上面三条规则只对 ES6 的浏览器实现有效,其他环境的实现不用遵守,还是将块级作用域的函数声明当作let处理

    块中生命函数,都会提升到函数头部,不管是“函数声明”还是函数表达式,都会是var f;的形式,所有调用的时候会报错

    展开全文
  • 3), 块级作用域-----ES6新增的,用{}来界定块级作用域。 1,块作用域由 { } 包括,if语句和for语句里面的{ }也属于块作用域。 2,ES6新增了块级作用域,使用let声明的变量只能在块级作用域里访问 if(true){ ...

    作用域

    作用域是标识符的可访问范围
    在Javascript常用三种作用域(词法环境):

    • 1),全局作用域------全局定义
    • 2), 函数作用域-------在函数内部定义
    • 3), 块级作用域-----ES6新增的,用{}来界定块级作用域。

    1,块作用域由 { } 包括,if语句和for语句里面的{ }也属于块作用域。

    2,ES6新增了块级作用域,使用let声明的变量有块的概念,var声明的变量则没有块级作域的概念;

    if(true){ var num = 100; }
    console.log(num);          //正常打印100
    
    if(true){ let age = 60; }
    console.log(age);          //报错:age is not defined
    

    注意
    var定义的变量,没有块的概念,可以跨块访问, 不能跨函数访问。
    let定义的变量, 有块的概念,不能跨块访问,也不能跨函数访问。
    const用来定义常量,有块的概念,不能跨块访问,而且不能修改。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    三种定义变量的常见问题(变量提升和暂存死区)

    1,变量提升(var在定义变量之前进行访问变量时所引起的现象)

      console.log(number);     // undefined
      var number = 1000;
      console.log(number);  // 1000
    

    var声明的变量能够提前使用虽然只是undefined, 我们把这种现象称之为变量提升

    2,暂存死区 (let在定义变量之前进行访问变量时所引起的现象)

    function do_something() {
      console.log(bar); // undefined
      console.log(foo); // ReferenceError: Cannot access 'foo' before initialization
      var bar = 1;
      let foo = 2;
    }
    do_something() ;
    

    在这里插入图片描述
    与通过 var 声明的有初始化值 undefined 的变量不同,
    通过 let 声明的变量直到它们的定义被执行时才初始化。在变量初始化前访问该变量会导致 ReferenceError。该变量处在一个自块顶部到初始化处理的“暂存死区”中。

    参考 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/let

    作者:糯米团子_大芒果
    链接:https://www.jianshu.com/p/6b6b322b6e4d
    来源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    展开全文
  • 主要介绍了ECMAScript6块级作用域及新变量声明(let) 的相关资料,需要的朋友可以参考下
  • js代码-闭包原理实例 ES5 只要函数作用域,无块级作用域
  • es6中块级作用域详解

    2019-09-23 11:21:29
    什么是块级作用域 ES6 中新增了块级作用域。块作用域由 { } 包括,if语句和 for语句里面的{ }也属于块作用域。 为什么需要块级作用域 第一种场景:内部变量会覆盖外部变量 var time = new Date() function zxx ...

    什么是块级作用域

    ES6 中新增了块级作用域。块作用域由 { } 包括,if语句和 for语句里面的{ }也属于块作用域。

    为什么需要块级作用域

    第一种场景:内部变量会覆盖外部变量

    var time = new Date()
    function fx () {
        console.log(time) // undefined
        if (false) {
            var time = 'hello'
        }
    }
    fx() 
    
    {
        var a = 1
        console.log(a) // 1
    }
    console.log(a) // 1
    // 通过var定义的变量可以跨块作用域访问到。

    第二种场景:用来计数的循环变量泄漏为全局变量

    var s = 'hello';
    
    for (var i = 0; i < s.length; i++) {
      console.log(s[i]);
    }
    
    console.log(i); // 5

    什么是块级作用域(ES6提供let变量实现块级作用域)

    function fxFn () { // 这是一个块级作用域
        let fx = 'fx is a great girl'
        if (true) { // 这是一个块级作用域
            let fx = 'fx is 18 years old'
        }
        console.log(fx) // fx is a great girl
    }
    fxFn()
    
    块级作用域之间相互不影响

    ES6 允许块级作用域的任意嵌套。

    {{{{
      {let insane = 'Hello World'}
      console.log(insane); // 报错
    }}}};

    上面代码使用了一个五层的块级作用域,每一层都是一个单独的作用域。第四层作用域无法读取第五层作用域的内部变量。

    内层作用域可以定义外层作用域的同名变量。

    {{{{
      let insane = 'Hello World';
      {let insane = 'Hello World'}
    }}}};

     块级作用域的出现,实际上使得获得广泛应用的匿名立即执行函数表达式(匿名 IIFE)不再必要了。

    // IIFE 写法
    (function () {
      var tmp = ...;
      ...
    }());
    
    // 块级作用域写法
    {
      let tmp = ...;
      ...
    }

    块级作用域与函数声明

    ES5 规定,函数只能在顶层作用域和函数作用域之中声明,不能在块级作用域声明。

    // 情况一
    if (true) {
      function f() {}
    }
    
    // 情况二
    try {
      function f() {}
    } catch(e) {
      // ...
    }

    上面两种函数声明,根据 ES5 的规定都是非法的。

    但是,浏览器没有遵守这个规定,为了兼容以前的旧代码,还是支持在块级作用域之中声明函数,因此上面两种情况实际都能运行,不会报错。

    ES6 引入了块级作用域,明确允许在块级作用域之中声明函数。ES6 规定,块级作用域之中,函数声明语句的行为类似于let,在块级作用域之外不可引用。

    function f() { console.log('I am outside!'); }
    
    (function () {
      if (false) {
        // 重复声明一次函数f
        function f() { console.log('I am inside!'); }
      }
    
      f();
    }());

    上面代码在 ES5 中运行,会得到“I am inside!”,因为在if内声明的函数f会被提升到函数头部,实际运行的代码如下。

    // ES5 环境
    function f() { console.log('I am outside!'); }
    
    (function () {
      function f() { console.log('I am inside!'); }
      if (false) {
      }
      f();
    }());
    

    ES6 就完全不一样了,理论上会得到“I am outside!”。因为块级作用域内声明的函数类似于let,对作用域之外没有影响。但是,如果你真的在 ES6 浏览器中运行一下上面的代码,是会报错的,这是为什么呢?

    // 浏览器的 ES6 环境
    function f() { console.log('I am outside!'); }
    
    (function () {
      if (false) {
        // 重复声明一次函数f
        function f() { console.log('I am inside!'); }
      }
    
      f();
    }());
    // Uncaught TypeError: f is not a function
    

    上面的代码在 ES6 浏览器中,都会报错。

    原来,如果改变了块级作用域内声明的函数的处理规则,显然会对老代码产生很大影响。为了减轻因此产生的不兼容问题,ES6 规定,浏览器的实现可以不遵守上面的规定,有自己的行为方式

    • 允许在块级作用域内声明函数。
    • 函数声明类似于var,即会提升到全局作用域或函数作用域的头部。
    • 同时,函数声明还会提升到所在的块级作用域的头部。

    注意,上面三条规则只对 ES6 的浏览器实现有效,其他环境的实现不用遵守,还是将块级作用域的函数声明当作let处理。

    根据这三条规则,浏览器的 ES6 环境中,块级作用域内声明的函数,行为类似于var声明的变量。上面的例子实际运行的代码如下。

    // 浏览器的 ES6 环境
    function f() { console.log('I am outside!'); }
    (function () {
      var f = undefined;
      if (false) {
        function f() { console.log('I am inside!'); }
      }
    
      f();
    }());
    // Uncaught TypeError: f is not a function
    

    考虑到环境导致的行为差异太大,应该避免在块级作用域内声明函数。如果确实需要,也应该写成函数表达式,而不是函数声明语句。

    // 块级作用域内部的函数声明语句,建议不要使用
    {
      let a = 'secret';
      function f() {
        return a;
      }
    }
    
    // 块级作用域内部,优先使用函数表达式
    {
      let a = 'secret';
      let f = function () {
        return a;
      };
    }
    

    ES6 的块级作用域必须有大括号

    如果没有大括号,JavaScript 引擎就认为不存在块级作用域。

    // 第一种写法,报错
    if (true) let x = 1;
    
    // 第二种写法,不报错
    if (true) {
      let x = 1;
    }
    

    上面代码中,第一种写法没有大括号,所以不存在块级作用域,而let只能出现在当前作用域的顶层,所以报错。第二种写法有大括号,所以块级作用域成立。

    函数声明也是如此,严格模式下,函数只能声明在当前作用域的顶层。

    // 不报错
    'use strict';
    if (true) {
      function f() {}
    }
    
    // 报错
    'use strict';
    if (true)
      function f() {}

     

    展开全文
  • var与let区别-详解块级作用域与局部作用域

    千次阅读 多人点赞 2020-06-10 19:27:49
    1.1-js三种作用域介绍 1.作用域概念(Scope) : 变量可以起作用的范围区域 1.1 ES5 有两种作用域 a.全局作用域(Global Scope) : 函数外面声明的变量,称之为全局变量。 可以在页面任何地方被访问 全局变量生命...
  • 由于 JavaScript 的变量提升存在着变量覆盖、变量污染等设计缺陷,所以 ES6 引入了块级作用域关键字来解决这些问题。 不聊存储栈和变量环境和**词法环境(**不清楚的百度) 只说不知道的let的变量提升 let myname= '...
  • JavaScript的执行机制——块级作用域

    热门讨论 2021-05-24 14:09:41
    块级作用域作用域(scope)变量提升所带来的问题变量容易在不被察觉的情况下被覆盖掉本应销毁的变量没有被销毁ES6 是如何解决变量提升带来的缺陷JavaScript 是如何支持块级作用域的 作用域(scope) 为什么 ...
  • 1.块级作用域 什么是块级作用域? {} 这个花括号里面的作用域就是块级作用域。 var i = 100 for(var i=0; i<5; i++){ console.log(i) //1,2,3,4 } console.log(i) //5 使用var的话就会导致在for循环里面的i...
  • 作用域:函数和变量的使用返回 全局作用域:函数外部的作用域 局部作用域;函数内部的作用域 一、全局作用域
  • 1.ES5只有全局作用域和函数作用域,没有块级作用域 这会带来一些不必要的麻烦 1.由于变量提升而导致内层变量覆盖外层变量 var tmp = new Date(); function f(){ console.log(tmp); if(false){ var tmp = ...
  • 本文实例讲述了JS块级作用域和私有变量。分享给大家供大家参考,具体如下: 块级作用域 (function(){ //这里是块级作用域 })() 例如: (function(){ for(var i=0;i<5;i++){ alert(i);//0,1,2,3,4 ...
  • 关于ES6中let 和 const 命令的用法以及注意事项:中的报错的样式ES6 引入了块级作用域,明确允许在块级作用域之中声明函数。ES6 规定,块级作用域之中,函数声明语句的行为类似于let,在块级作用域之外不可引用。
  • //报错 块级作用域中函数声明可以打断点,但在局部作用域中不能打断点,也就是说在块级作用域中函数声明会执行,但在局部作用域中函数声明,只做声明,本身自身不执行 块级:块级作用域中的函数在预编译的时候会被...
  • 在ES6中新引入了“块级作用域”这一概念,伴随这一概念诞生的是两种新的变量声明方法,他们依赖于块级作用域而存在。 一、pandas是什么? 示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建...
  • 块级作用域的作用

    2020-03-10 15:46:09
    在es5中只有全局作用域和函数作用域,导致一些场景不合理 1. 内层变量会覆盖外层变量 var tmp = new Date(); function f(){ console.log(tmp) if(false){ var tmp = 'hello' } } f()//undefined 原因...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 37,419
精华内容 14,967
关键字:

块级作用域