zl程序教程

您现在的位置是:首页 >  后端

当前栏目

ES6小知识

ES6 知识
2023-09-27 14:29:06 时间

1.let 和 const 命令

在es5时,只有两种变量声明,var 和function。在es6中新增了四种let和const,以及另外两种声明import和class。 我们先讲解let和const,后续会补充import和class

(1)let

我们先来看基本语法

{
 let a = 10;
 var b = 1;
}
b // 1
a // ReferenceError: a is not defined.
复制代码

我们在代码块中声明了a,b。然后a is not defined.这是因为let命令只在对应的代码块中有效,我们在外部去引用它,就会报错。这就是let的块级作用域的效果,如果不太清楚什么是块级作用域。我们来看下面的例子

var a = [];
for (var i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[0]();//10
a[6](); // 10
复制代码

这是一个老生常谈的问题了。i在for循环中定义的是全局变量。我们在调用函数时。函数内部的i引用的是全局的i,所以打印出来的 是10. 我们之前是这样解决的。

 var a = [];
    for (var i = 0; i < 10; i++) {
        a[i] = (function (a) {
            return function(){
                console.log(a);
            }
        }(i));
    }
    a[0]();//0
    a[6](); // 6
复制代码

我们使用了立即执行函数将i的值传入了内部的函数,这样内部的函数就能够获取到对应的i。

我们用let来代替var,最后输出的是 6。

var a = [];
for (let i = 0; i < 10; i++) {
 a[i] = function () {
   console.log(i);
 };
}
a[6](); // 6
复制代码

这是因为我们每一次的循环都生成了一个新的块级作用域,内部保存着i的值,所以就会打印出6.

let不存在变量提升

   console.log(a);
   console.log(b);
   var a=0;//undefined
   let b=0;//ReferenceError: b is not defined
复制代码

TDZ(暂时性死区) let命令在块级作用域中,即使不存在变量提升,它也会影响当前块级作用域,即绑定在了当前作用域。在作用域中引用外部的变量将会报错。

 var a=10;
  {
      console.log(a);  //ReferenceError: a is not defined
      let a=10;
  }
复制代码

同时,我们在TDZ中使用typeof也会报错.

 console.log( typeof a);//undefined
复制代码
console.log( typeof a);//ReferenceError: a is not defined
  let a=10;
复制代码

let 不允许重复声明变量

{
    var a=0;
    let a=1;//SyntaxError: Identifier 'a' has already been declared
}
复制代码

(2) const常量

const常量声明一个只读属性的变量,不可更改,不可先声明后赋值,生成块级作用域。

 const a;//SyntaxError: Missing initializer in const declaration(const声明中缺少初始值设定项)
 a=10;
复制代码

它同let有很多相似的地方。 .不可重复声明

const a=10;
var a=10;//SyntaxError: Identifier 'a' has already been declared
复制代码

.变量不提升

console.log(a)//ReferenceError: a is not defined
const a=10;
复制代码

.同样存在暂时性死区

var a=10;
{
    console.log(a);//ReferenceError: a is not defined
    const a=10;
}
复制代码

另外,const保证常量的值不被修改的原理是什么呢?const实际上无法改变的只是常量在栈区的值不变,如果这个值是一个基本数据类型,那么const能够保障常量的值不变,但如果是引用类型的数据,栈区保存的其实是对应常量的地址。地址无法改变,但是对应地址的堆区内容却可以改变。

 const a=[1,2,3]
 a.push(4)
 console.log(a); //[1, 2, 3, 4]
复制代码

很显然,我们通过push,直接修改了堆区的内容,间接改变了const常量的值。

如果要真正做到常量的功能,可以使用Object.freeze()

var a=[1,2,3];
Object.freeze(a)
a.push(4)  //Cannot add property 3, object is not extensibleat Array.push
console.log(a);
复制代码

2.字符串扩展方法

(1)for of字符串遍历

使用for of可以遍历字符串,并将字符串分解为单独的字符串

var a='lang'
for (item of a){
  
   console.log(item);
} 
// l
// a
// n
// g
复制代码

(2) codePointAt字符串查询.

根据下标,查询对应字符串。在Es5时,就有一个charAt()方法。但charAt()显然没想到,随着Unicode编码的扩展,原先的0x0000~0xFFFF已经无法满足表示所有字符了。

var text = "