美文网首页
let 和 const 命令

let 和 const 命令

作者: 灬劣徒 | 来源:发表于2019-11-25 09:46 被阅读0次
图片.png
ES6声明变量的六种方法

ES5只有两种声明变量的方法:var和function命令。ES6除了添加let和const命令,后面章节还会提到,另外两种声明变量的方法:import命令和class命令。所以,ES6一共有六种声明变量的方法。

let命令

ES6新增了let命令,用法类似于var,但是有区别

① let命令只在所在代码块内有效
② 不存在变量提升

var命令会发生“变量提升”现象,即变量可以在声明之前使用,值为undefined。这种现象多多少少是有些奇怪的,按照一般的逻辑,变量应该在声明语句之后才可以使用。
为了纠正这种现象,let命令改变了语法行为,它所声明的变量一定要在声明后使用,否则报错。

③ 暂时性死区

在代码块内,使用let声明变量之前的区域,该变量都不可用,此被称为“暂时性死区”
(个人理解:因为没有了变量提升,才会造成‘暂时性死区’说法,但是为什么不叫永久性死区呢??)
暂时性死区有以下几个影响:

1.typeof 不再是一个安全的操作
typeof x //报错
let x;

2.作为比较,如果一个变量没有被声明,使用typeof反而不会报错。
typeof  y // "undefined"

3.有些死区比较隐蔽,不太容易被发现
function bar(x = y,y = 2) {
 return [x,y];
}
bar() //报错,因为参数x的默认值等于另一个参数y,而此时y还没有被声明

4.使用let生命变量,只要变量在还没有声明完成前就使用,就会保错
var x = x; //不报错
let x = x; //报错
④ 不允许重复声明

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

function bar() {
  let a = 10;
  var a = 1;
}
//报错

function brp() {
  let a = 10;
  let a = 1;
}
//报错

function bup(arg) {
    let arg;
}
bup(); //报错

function bpg(arg){
  {
    let arg;
  }
}
bpg(); //不报错 

const命令

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

//变量的值不可更改
const PI = 3.1415;
PI = 3; //报错

//const声明变量必须立即初始化,不能留到以后赋值
const foo; //报错

//const作用域与let相同:只在声明所在的块级作用于内有效
if(true){
  const MAX = 5;
}
MAX; //MAX is not defined

// const命令声明的变量也是不提升,同样存在暂时性死区,只能在声明之后的位置使用
if(true)  {
   console.log(MAX); //报错
  const MAX = 5;
}

本质:const 实际上保证的,并不是变量的值不可改变,而是变量指向的那个内存地址所保存的数据不得改动。对于简单类型的数据(number、string、boolean),值就保存在变量指向的内存地址,保存的只是一个指向实际数据的指针,const 只能保证这个指针是固定的(即总是指向另一个固定的地址),至于它指向的数据结构是不是可变的,就完全不能控制了。因此,将一个对象声明为常量必须非常小心。

const foo = {};
foo.prop = 123; // 为fool添加一个新属性,可以成功
foo.prop  //123
foo = {}; //把 fool指向另一个地址,则报错

//如果真的想将对象冻结,应该使用Object.freeze方法;
const foo = object.freeze({});
foo.prop = 123;

...

顶层对象的属性

顶层对象,在浏览器环境指的是window对象,在Node指的是global对象。ES5之中,顶层对象的属性与全局变量是等价的。

window.a = 123;
a; // 123
a = 321;
window.a; // 321

上面代码中,顶层对象的属性赋值与全局变量的属性赋值是同一件事。

顶层对象的属性与全局变量挂钩,被认为是JavaScript语言最大的设计败笔之一。这样的设计带来了几个很大的问题,首先是没法在编译时就报出变量未声明的错误,只有运行时才能知道(因为全局变量可能是顶层对象的属性创造的,而属性的创造是动态的);其次,程序员很容易不知不觉就创建了全局变量(比如打字出错);最后,顶层对象的属性是到处可以读写的,这非常不利于模块化编程。另一方面,window对象有实体含义,指的是浏览器的窗口对象,顶层对象是一个有实体含义的对象,也是不适合的。

ES6为了改变这一点,一方面规定,为了保证兼容性,var命令和function命令声明的全局变量,依旧是顶层对象的属性;另一方面规定,let命令、const命令、class命令声明的全局变量,不再属于顶层对象的属性。也就是说,从ES6开始,全局对象将逐步与顶层对象的属性脱钩。

var a = 123;
window.a; // 123

let a = 123;
window.a; //undefined;

...

globalThis对象

JavaScript语言存在一个顶层对象,它提供全局环境(即全局作用域),所有代码都是在这个环境中运行。但是顶层对象在各种实现里面是不统一的。

--在浏览器环境,顶层对象是window、self
--Web Worker里面,顶层对象是self
--Node里面,顶层对象是global,但其他环境都不支持。

同一段代码,为了能够在各种环境下都能渠道顶层对象,现在一般是使用this变量,但是有局限性:
①全局环境中,this会返回顶层对象,但是在node和ES6模块中,this返回的是当前模块。
②函数里面的this,如果函数不是作为对象的方法运行,this会指向顶层对象。但是,严格模式下, this会返回undefined。
③不管是严格模式,还是普通模式,new Function('return this')(),总是会返回全局对象。但是,如果浏览器用了CSP(Content Security Policy,内容安全策略),那么eval、new Function 这些方法都可能无法使用。

综上所述,很难找到一种方法,可以在所有情况下,都取到顶层对象。下面是两种勉强可以使用的放大。

//方法1:
(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');
}

相关文章

  • let和const

    新的赋值语句let和const let和const命令

  • ES6的let 和 const 命令

    let 和 const 命令 let 命令 块级作用域 const 命令 顶层对象的属性 gl...

  • ES6需要记忆理解的地方

    let和const命令 1、let和const均无变量提升。2、let变量指向的地址可变,const指向的地址不可...

  • 重读 ES6(一)

    一、let 和 const 命令 let 命令 let 与 var 的区别:let 声明的变量只在 let 命令所...

  • js 中var contst let 之间的区别

    ECMAScript 6 新增 const 和 let 命令,用来声明变量。 那么const,let和var 在声...

  • es6常用语法(一)

    let 和 const 命令 let 命令 只在let命令所在的代码有效 let命令,用来声明变量。它的用法类似于...

  • es6总结一

    es6基础 let和const命令 let和const用于声明变量let跟var的区别 1、let定义过的变量不能...

  • ES6笔记

    let 和 const ES6 明确规定,如果区块中存在let和const命令,这个区块对这些命令声明的变量,从一...

  • ECMAScript 6 入门

    1.let 和 const 命令 let 命令 基本用法 ES 6 新增了 let 命令,用来声明变量,它的用法类...

  • ES6基础入门

    变量 let 命令 const 命令 函数

网友评论

      本文标题:let 和 const 命令

      本文链接:https://www.haomeiwen.com/subject/dfjiyctx.html