ES6学习笔记2--let命令与const命令

let命令

let 声明变量,只在他所在的代码块有效

var 声明变量,在全局范围内有效

let 不会存在变量提升问题,let所声明的变量一定要在声明后使用。

var 存在变量提升,变量可以在声明之前使用,值为undefined。

let 不允许在相同作用域内,重复声明同一个变量。

  • 暂时性死区

如果区块中存在let const 命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。

凡是在声明之前就使用使用这些变量,就会报错。

在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为 "暂时性死区"(Temporal dead zone,简称TDZ)。

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

//sample
//在代码块外var 声明变量tmp
//在代码块内使用 let 声明变量tmp,若在声明之前使用变量tmp,即形成"暂时性死区(TDZ)"

var tmp=123

if(true){
    //TDZ开始
    tmp = 'abc'; //ReferenceError
    console.log(tmp); //ReferenceError
    let tmp;
    //TDZ 结束
    console.log(tmp);//undefined
    tmp = 123 
    console.log(tmp);//123
}

 

  • 块级作用域

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

ES6 允许块级作用域的任意嵌套,应避免在块级作用域内声明函数。若需要,应写成函数表达式而不是函数声明语句。具体原因

const命令

const声明一个只读的常量,一旦声明,常量的值就不能改变。

const 的作用域与let命令相同:只在声明所在的块级作用域内有效。

const 声明的常量也不提升,同样存在暂时性死区。

const 实际上保证的并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动。

对于简单类型的数据(数值,字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。

但对于复合类型的数据(对象、数组)变量指向的内存地址,保存的只是一个指向实际数据的指针,const只能保证这个指针是固定的(即总是指向一个固定的地址)。但他所指向的数据结构可以发生改变

//声明一个foo常量对象,常量foo在内存中储存的是一个地址。不可变的是地址
//不能将foo指向另一个地址,但对象本身是可变的,依然可以添加新属性

const foo = {}
//为foo添加一个属性.
foo.prop = 123

console.log(foo.prop) //123

//将foo指向另一个对象,就会报错

foo = {}; //TypeError: "foo" is read-only


//若想要对象冻结,应该使用 Object.freeze()方法

const foo = Object.freeze({});

//常规模式下,下面一行不起作用
//严格模式下('use strict'),会报错。
foo.prop = 123;

//除了将对象本身冻结,对象的属性也应该冻结。下面是一个将对象彻底冻结的函数

var constantize =(obj)=>{
    Object.freeze(obj);
    Object.keys(obj).forEach((key,i)=>{
        if(typeof obj[key] === 'object'){
            constantize(obj[key]);
        }
    })
}

 

  • 顶层对象的属性

顶层对象,在浏览器环境指的是 window 对象,在Node指的是global对象。

在ES5中,顶层对象的属性与全局变量是等价的。

ES6中 一方面规定  为保持兼容性,var 命令和function命令声明的全局变量,依旧是顶层对象的属性。

另一方面规定,let const class 命令声明的全局变量,不属于顶层对象的属性。

  • globalThis对象

JavaScript 语言存在一个顶层对象,他提供全局环境(即全局作用域)。所有代码都是在这个环境中运行。

但是顶层对象在各个环境的实现是不统一的。

  • 浏览器中顶层对象是window,但Node 和Web Worker 没有window
  • 浏览器和Web Worker里面,self 也指向顶层对象,但是Node 没有self
  • Node里面,顶层对象是global,但其他环境不支持。

为同一段代码能够在各种环境,都能取到顶层对象,现在一般使用 this 变量,但有一定的局限性

  • 全局环境中,this 会返回顶层对象。但是Node 模块和ES6模块中,this 返回的是当前模块
  • 函数里面的this,如果函数不是作为对象的方法运行,而是单纯作为函数运行,this 会指向顶层对象。但是严格模式下,这时this 会返回undefined
  • 不管是严格模式还是普通模式下,new Function('return this')(),总是会返回全局对象。但是,如果浏览器用了CSP(Content Security Policy),evalnew Function 这些方法都可能无法使用。

综上所述很难找到一种方法,在所有情况下,都取到顶层对象。

所以引入 globalThis 作为顶层对象。在任何环境下,globalThis 都是存在的,都可以从他拿到顶层对象,指向全局环境下的this

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值