阮一峰es6第二章读书笔记-let和const命令

1. let命令

基本用法

  • 作用:用来声明变量

  • 与var区别:let声明的变量的有效范围是let命令所在的代码块,而var声明的变量是全局范围

  • 例子 :

    {
      let a = 10;
      var b = 1;
    }
    
    a // ReferenceError: a is not defined.
    b // 1
    
  • 一般可以使用在for循环中,如for(let i = 0;i<10;i++)

  • for循环的一个特别之处,设置循环变量的部分是父作用域,而循环体内容是一个单独的子作用域

  • 例子

    for (let i = 0; i < 3; i++) {
      let i = 'abc';
      console.log(i);
    }
    // abc
    // abc
    // abc
    

不存在变量提升

  • let命令声明的变量不存在变量提升,而var命令声明的变量则会有变量提升,什么是变量提升呢,就是变量在声明之前就可以使用,但是值为undefined。

  • 例子

    // var 的情况
    console.log(foo); // 输出undefined
    var foo = 2;
    
    // let 的情况
    console.log(bar); // 报错ReferenceError
    let bar = 2;
    

暂时性死区

  • 意思就是一变量在某个区域内用let声明,那么在该区域内,任何在let声明该变量之前调用这个变量都会报ReferenceError错误

  • 例子

    if (true) {
      // TDZ开始
      tmp = 'abc'; // ReferenceError
      console.log(tmp); // ReferenceError
    
      let tmp; // TDZ结束
      console.log(tmp); // undefined
    
      tmp = 123;
      console.log(tmp); // 123
    }
    
    • 比较难看到错误的例子
    function bar(x = y, y = 2) {
      return [x, y];
    }
    
    bar(); // 报错
    

    之所以报错,是因为x=y执行的时候,y还没有声明,所以把报错

  • 暂时性死区的本质:只要一进入当前作用域,所要使用的变量就已经存在,但是不可获取,必须等到明确声明变量的一行代码出现,才可以获取和使用该变量

不允许重复声明

  • let不允许在相同的作用域内,重复声明一个变量,因此不能在函数内部重新声明函数的参数,除非你在函数内部的再加一个子作用域,就可以在自作用域内声明与参数同名的变量。

块级作用域

为什么需要块级作用域

  • 只有全局作用域和函数作用域会造成:①内层变量可能会覆盖外层变量 ②用来计数的循环变量泄露为全局变量

    • 对于第一种 例子:
    var tmp = new Date();
    
    function f() {
      console.log(tmp);
      if (false) {
        var tmp = 'hello world';
      }
    }
    
    f(); // undefined
    

    内层if语句的tmp覆盖了外层时间的tmp

    • 对于第二种 例子
     var s = 'hello';
    
    for (var i = 0; i < s.length; i++) {
      console.log(s[i]);
    }
    
    console.log(i); // 5
    

    i变成了全局变量

ES6的块级作用域

  • let创造了块级作用域,使得外层作用域无法读取内层作用域的变量,并且内层作用域可以定义外层作用域的同名变量。

    • 例子
     function f1() {
      let n = 5;
      if (true) {
        let n = 10;
      }
      console.log(n); // 5
    }
    

    这个例子,如果都是用var的话,n就会编程全局变量,结果为10

块级作用域与函数声明

  • ES6规定,函数可以在块级作用域中声明,并且块级作用域外不能调用该函数。
  • 浏览器实现
    • 允许在块级作用域内声明函数
    • 函数声明类似于var,即会提升到全局作用域或函数作用域的头部
    • 同时,函数声明还会提升到所在的块级作用域的头部
  • 其他地方则把块级作用域的函数声明当做let处理
  • 最佳实践:由于韩静导致行为差异太大,所以应该避免在块级作用域内声明函数,如果确实需要,那么携程函数表达式形式
  • 其他注意事项:ES6 的块级作用域允许声明函数的规则,只在大括号的情况下成立,所以if后面一定要加括号,即使后面只有一句话。

const 命令

  • 作用:声明一个只读的常量。一旦声明,常量的值就不能改变

  • const声明的变量一旦声明就必须马上初始化,不能以后赋值,否则会报错

    const foo;
    // SyntaxError: Missing initializer in const declaration
    
  • const与let类似只在声明所在的块级作用域内有效,同样存在暂时性死去,只能在声明的位置之后使用,同样不能重复声明。

本质

  • const实际上保证不是说变量的值不能改动,而是变量指向的那个内存地址所保存的数据不得改动,那么对于简单的数据类型(数值,字符串,布尔值)来说,它们的值就保存在变量所指的地址,因此等同于变量,但是对于函数或数组来说,变量指向的内存地址,保存的知识一个指向实际数据的指针,const只能保证这个指针是固定的,(即总是执行另一个固定的地址),至于它指向的数据结构就可以变化了。例子

    const foo = {};
    
    // 为 foo 添加一个属性,可以成功
    foo.prop = 123;
    foo.prop // 123
    
    // 将 foo 指向另一个对象,就会报错
    foo = {}; // TypeError: "foo" is read-only
    

    简单来说,就是const只能保证变量是指向这个对象或这个数组,这点是不能变化的,但是对象或数据里面的内容则不能管理到。

Object.freeze方法

  • 作用:将对象冻结,使之不能添加新的属性

  • 例子

     const foo = Object.freeze({});
    
    // 常规模式时,下面一行不起作用;
    // 严格模式时,该行会报错
    foo.prop = 123;
    

ES6声明变量的六种方法

六种方法分别是:var function let const import class

顶层对象的属性

  • 顶层对象,浏览器中指window对象,node中指global对象,ES5中顶层对象的属性与全局属性是等价的 例子:

    window.a = 1;
    a // 1
    
    a = 2;
    window.a // 2
    
  • 顶层对象与全局变量等价造成的问题:①没法在编译时就爆出变量未声明的错误②程序员很容易不知不觉就创建了全局变量③顶层对象的属性到处可以读写,不利于模块化编程。

  • ES6将全局变量逐步与顶层对象的属性脱钩:表现在varfunction命令声明的全局变量依旧是顶层对象属性,但let命令,const命令、class命令声明的全局变量不属于顶层属性。例子

    var a = 1;
    // 如果在 Node 的 REPL 环境,可以写成 global.a
    // 或者采用通用方法,写成 this.a
    window.a // 1
    
    let b = 1;
    window.b // undefined
    

global对象

global是ES5的顶层对象,但在各种实现里面不统一。

  • 浏览器里面,顶层对象是window,但Node和Web Worker没有window。

  • 浏览器和Web Worker里面,self也指向顶层独享,但是Node没有self

  • node里面,顶层对象是golbal,但其他环境不支持
    而为了一段代码能在各种环境都能取到顶层对象,一般用this变量,但是有它的局限性

  • 全局环境中,this会返回顶层对象,但是,node模块和es6模块中,thils返回的是当前模块

  • 函数里面的this,如果不是作为对象的方法运行,而是单纯作为对象运行,this会指向顶层对象,但是,严格模式下,这时this会返回undefined。

  • 不管是严格模式,还是普通模式,new Function(‘return’)()总是会返回全局对象。
    因此很闹找到一种方法在所有情况下,都取到顶层对象,下面是两种勉强可以使用的方法。

    // 方法一
    (typeof window !== 'undefined'
       ? window
       : (typeof process === 'object' &&
          typeof require === 'function' &&
          typeof global === 'object')
         ? global
         : this);
    
    // 方法二
    var getGlobal = function () {
      if (typeof self !== 'undefined') { return self; }
      if (typeof window !== 'undefined') { return window; }
      if (typeof global !== 'undefined') { return global; }
      throw new Error('unable to locate global object');
    };
    

参考资料

阮一峰的es6教程

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容