ES6系列入门学习记录:let和const

前言

感谢你能点进这篇文章,首先我先作一个说明,我是今年刚毕业的前端应届生,这篇文章是我学习ES6的letconst部分以后,本身作的概括笔记,也是个人第一篇文章。第一次作这种文章类的分享,并且是在一个大平台上,若是有不足,但愿能够帮我点出,十分感谢。前端

其实在发表文章以前,咱们公司前端组的大佬就一直鼓励我去作文章分享,打造本身的一个品牌。可是因为本身性格问题和懒惰,一直在拖。毕竟我最开始并不以为本身有什么能分享的,可是后续慢慢的才理解到一个真理:分享是没有门槛的。因此开始尝试作这种事情,但愿能够慢慢作好,毕竟也是对本身的一种提高和锻炼。以后会继续更新ES6的学习记录文章,文章的内容,都是经过本身理解以后,而后用本身的话语去进行一个描述,当中可能会有不太准确或者不太恰当的描述,也欢迎观看文章的您提出这类的意见和建议。同时个人文章会进行一些内容的验证,有些部分可能会验证的有点多,也请多担待。es6

最后补充一句,我目前ES6系列学习的主要文献是阮一峰大神的《ECMAScript 6 入门》chrome

那就正式开始吧。浏览器

Let命令

let命令用于声明变量,用法相似于var,可是let命令有个特色那就是只会做用在let所在的做用域内。bash

Let命令的做用域

let a = 1;
{
    var b = 2;
    var c = a;
    let d = 3;
 }
 
 a // 1
 b // 2
 c // 1
 d // ReferenceError: b is not defined
复制代码

这里的a参数的let命令用法毫无心义,若是这样使用就和var没区别,倒不如说要这样使用还不如使用varide

for循环则很是适合使用该命令函数

for(let i=0;i<1;i++){
   console.log('A',i);
}
console.log('B',i);

// A 0 
// ReferenceError: i is not defined
复制代码

for循环中使用let命令,每一轮循环的i都是一个新的变量,若是在内部使用计算公式等,则会经过JavaScript引擎记住上一轮循环结果的值,而后对其进行后续的循环计算,总而完成计算。学习

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

// a
// a
// a
复制代码

此处是在for循环中使用let时候的一个特色,当子做用域中使用let再次定义了一个与父做用域中相同名称的参数时,两个参数互不干扰。测试

暂时性死区

只要块级做用域内存在let命令,它所声明的变量就“绑定”这个区域,再也不受外部的影响。ui

let a = 1;
let b = 1;
{
   let a = 2;
   b = 2;
   console.log('a1',a);
   console.log('b1',b);
}
console.log('a2',a);
console.log('b2',b);

// a1 2
// b1 2
// a2 1
// b2 2
复制代码

当分别在父做用域子做用域内使用let定义参数时,即使参数名相同,他们也不是同一个参数。父做用域中定义的参数,只会做用在自身做用域未从新使用let命令定义同名参数的子做用域中。该状况就是自做用于中的let命令产生了暂时性死区。

var a = 1;
{
    console.log(a)
    let a = 2;
}

// ReferenceError: a is not defined
复制代码

以上代码可知,做用域内只要使用了let命令声明的参数,即使有同名全局变量,也没法在let命令代码执行以前对该参数进行任意操做,即便这个操做和let命令是属于同一个做用域

let的暂时性死区的特色, 会致使任意做用域,只要某个参数有对应的let声明,不管该声明的位置在哪,该做用域内的该参数,便会彻底独立于在该做用域内,不会受到全局或者父做用域中同名参数的干扰。

不容许重复声明

注意一点,let命令是个小贪心鬼,同做用域内不容许有其余同名参数,不管是第二次同名命名是使用var仍是let,都会报错。其子做用域中,也必须使用let命令进行同名命名,不然也会报错。

let a = 1;
let a = 2;
console.log(a);

// Identifier 'a' has already been declared
复制代码
var a = 1;
let a = 2;
console.log(a);

// Identifier 'a' has already been declared
复制代码
let a = 1;
var a = 2
console.log(a);

// Identifier 'a' has already been declared
复制代码
var a = 1;
var a = 2;
console.log(a);

//  2
复制代码
let a = 1;
{
	var a = 2;
	console.log(a);
}
console.log(a);
复制代码

以上代码若在chrome调试面板测试时,请切记手动改参数名或者清除上一次代码所命名的参数。

Let命令不存在变量提高

所谓变量提高,就是变量能够在声明代码以前使用,不会出现报错,不过值未undefinedvar便有该特色。

console.log(a);
var a = 1;
// undefined

console.log(b);
let b = 1;
// Identifier 'b' has already been declared
复制代码

使用var命令声明的参数,即会发生变量提高的参数,在脚本开始运行时,对应的变量就已经被建立,直到执行到实际定义参数的代码时,该参数才会被赋上对应的值。

块级做用域与函数声明

概念

在ES5中,通常只有全局做用域和函数做用域。

而在ES6中,增长了一个块级做用域。ES6 规定,块级做用域之中,函数声明语句的行为相似于let,在块级做用域以外不可引用。

通常而言,每一个{}内部就是一个块级做用域。

function f() { console.log('I am outside!'); }

(function () {
  if (false) {
    function f() { console.log('I am inside!'); }
  }

  f();}());
  
// Uncaught TypeError: f is not a function
复制代码

上述代码在ES6环境中执行的时候,会出现报错,由于两次声明的function和执行的f()不在同一块级做用域。

注意点

ES6改变了块级做用域内声明的函数的处理规则,可是因为互联网目前的现状是多个版本环境同时并行的状况。因此ES6有如下规定:

  • 容许在块级做用域内声明函数
  • 函数声明相似于var,即会提高到全局做用域或函数做用域的头部。
  • 同时,函数声明还会提高到所在的块级做用域的头部。

以上规则只对ES6的浏览器生效。在其余环境下不会生效。

综上所述,咱们须要尽可能避免在块级做用域内声明函数。若是没法避免,也要写成函数表达式。而且块级做用域的声明函数规则,必须在使用{}的状况下使用,不可使用简写。

if(true) 
    function f() {}
//报错
复制代码

const命令

概念

const用于声明一个只读的常量。

特色

因为const声明的常量为只读,因此其声明的常量没法修改。

const a = 123;

 a //123
 
 a = 321; // TypeError: Assignment to constant variable.
复制代码

声明的常量不能再次修改,因此意味着他必须在声明的时候就进行赋值。由于若是不这样作,你的声明就没有意义。

const a; // SyntaxError: Missing initializer in const declaration
复制代码

constlet类似,只在块级做用域内生效,同时也不提高和存在暂时性死区。

if(true){
   const a = 1;
}

a // ReferenceError: a is not defined


if(true){
   console.log(b);
   const b = 1;
}
//ReferenceError: b is not defined
复制代码

同时也和let命令同样,在同一块级做用域内,不可重复使用同样的名称,即使一个是声明常量,一个是声明变量。

var a = 1;
   let b = 1;
   
   const a = 2; // SyntaxError: Identifier 'a' has already been declared
   const b = 2; // SyntaxError: Identifier 'b' has already been declared
复制代码

本质

const并非变量的值不可改变,而是变量所指向的那个内存地址所保存的数据不得改变。特别是复合类型的数据,变量指向的内存地址,保存的只是一个指向实际数据的指针,const只能保证指针是固定的。

听起来其实有点绕,我我的的理解是,好比你须要调某个仓库的货物,而后我告诉你仓库的地址,我只能保障那个仓库的位置在那里不变,可是仓库里面放什么我就没法保证了。

const a = {};

a.prop = 1;
a.prop; // 1
复制代码

所以,使用const声明的时候须要格外当心,否则就是红红的报错了。(虽然快过年了,可是代码仍是别增添顾念的气氛了)

一些小补充

顶层对象的属性

在ES5中,顶层对象的属性和全局变量是等价的,也就是说全局变量的a = 1 等同于 window.a = 1

ES6中,为了改变这个状况,给varfunction命令保留了原有的这个特性的同时。也规定了letconstclass等命令所声明的全局变量,不属于顶层对象的属性。

var a = 1;
window.a //1

let b = a;
window.b //undefined
复制代码

总结

第一篇结束了,一开始写的时候特别乱,而后慢慢调整成了目前这一篇。若是你以为还能够,但愿能够帮点个赞。以后的更新我会继续奉上,也但愿能受到你的喜欢和收到你的意见和建议,十分感谢。

相关文章
相关标签/搜索