ES6 简单回顾

思而行 / 2023-09-03 / 原文

针对 Vue 中使用的 ES6 的知识点进行基本的回顾。

关键字

变量常量、解构赋值、模板字符串、扩展运算符
对象声明简写、箭头函数

1. 变量、常量

1.1 变量

声明变量可以使用 varlet,其中 var 对于语法规则的要求并不严格,而 let 声明变量较之严格了许多,let 声明变量可以联系 Java 声明变量进行联想记忆。
接下来将分别 2 个方面介绍 var 和 let 的区别。

  • 1)作用域:
    • var 声明的变量没有局部作用域,可以简单认为 var 声明出的变量为全局变量。
    • let 声明的变量有局部作用域,是有它自己的生命周期的。
<script>
  // 这是一个代码块
  {
    var global = 12; // var 声明一个全局变量
    
    let local = 12;  // let 声明一个局部变量
  }
  // 变量local 的生命周期结束
  
  // 尝试输出 上述 两个变量
  console.log(global);
  console.log(local);
</script>

输出结果:
image.png

  • 2)多次声明:
    • var 的语法规则不强,同一个名称的变量可以重复声明。多个同名变量反复声明,引用时只使用最后一次声明的同名变量。
    • let 不允许在同一个作用域内,反复声明相同名称的变量,这一点和 Java 的变量声明一致。
<script>
  // var 反复声明 同一名称的变量
  var global = 12;
  var global = 1;
  console.log('gloobal:',global);
  
  // let 反复声明 同一名称的变量
  let local = 12;
  let local = 1;
  console.log('local:',local);
  
  // 尝试输出 上述 两个变量
  console.log(global);
  console.log(local);
</script>

输出结果:
image.png
稍作修改,将第 2 个 local 变量放入代码块中

<script>
  // var 反复声明 同一名称的变量
  var global = 12;
  var global = 1;
  console.log('gloobal:',global);
  
  // let 反复声明 同一名称的变量
  let local = 12;
  {
      let local = 1;
      console.log('代码块内 local:',local);
  }
  console.log('local:',local);
  
  // 尝试输出 上述 两个变量
  console.log(global);
  console.log(local);
</script>

输出结果:
image.png

1.2 常量

const 用于常量的声明。这部分可以与 Java 中 final 声明常量进行联想记忆。但要注意,const 声明常量时需要赋初值,此后不能进行修改。
而在 Java 中,final 声明变量时,语法规则并没有强制要求赋予初值,不赋初值可以通过编译。但同样,一旦赋初值之后便不能进行修改。

<script>
  // const 声明常量
  const msg = 'Hello ES6';
</script>

2. 解构赋值

解构赋值只是一种赋值方式,将 数组 或 对象 提取出值(解构) 并将其赋值给变量的方式。
需要注意的是,对数组进行解构赋值的时候使用的是中括号 [],对象进行解构赋值的时候使用的是 花括号 {}、这点可以通过 数组 和 对象的赋值方式进行记忆。

2.1 数组解构赋值

<script>
  // 声明并初始化 数组
  const numArr = [1,5,1,12];
  console.log(numArr);
  
  // 进行解构赋值 - 全部
  const [num1,num2,num3,num4] = numArr;
  console.log('解构赋值结果-全部:',num1,num2,num3,num4);
  
  // 进行解构赋值 - 部分
  const [n1,n2] = numArr;
  console.log('解构赋值结果-部分:',n1,n2);
</script>

image.png

2.2 对象解构赋值

需要注意:进行解构的时候 变量声明的名称需要和 对象内成员变量的名称一致,若不一致则无法从对象里解构出需要的值。

<script>
  // 声明对象并初始化
  const person = {
      name:'Hollow Knight',
      age:'INF',
      weapon:'骨钉'
  }
  console.log(person);

  // 1- 若变量名称 和 对象的成员变量名称不一致
  // 进行解构赋值 - 全部
  const {n1,a1,w1} = person;
  console.log('不一致,对象解构赋值-全部',n1,a1,w1);

  // 2- 若一致
  // 进行解构赋值 - 部分
  const {name,weapon} = person;
  console.log('一致,对象解构赋值-部分',name,weapon);
</script>

image.png

3. 模板字符串

用于拼接字符串的方式,它是一种包含占位符的字符串语法,使用反引号 包裹字符串,并通过 ${} 插入变量或表达式。

<script>
    const info = 'Tomorrow';
    // 1):插入变量
    const msg1 = `Hello ${info}`;
    
    // 2) : 表达式求值
    const msg2 = `Tell me 1+1=${1+1}`;
    
    // 3) :多行文本
    const msg3 = `
    first row,
    second row,
    third row.
注意:上面那些空格也被包含进去了。
一行,
二行
    `;
    
    // 控制台输出
    console.log(msg1);
    console.log(msg2);
    console.log(msg3);
</script>

image.png

4. 扩展运算符

扩展运算符数字是在 ES6 中引入的语法,用于展开数组或对象。可以理解为将 数组或对象 内的值进行取出。它可以方便再函数调用、数组字面量和对象字面量中展开可迭代对象,将它们展开为单独的元素。

4.1 函数调用中的扩展运算符

<script>
    // 声明函数
    function sum(num1,num2,num3){
      console.log(`num1:${num1}, num2:${num2}, num3:${num3}`);
      return num1+num2+num3;
    }
    
    
    const numArr = [1,2,3];
    const numObj ={num1:1, num2:3, num3:2};
    
    // 调用函数,使用扩展运算符填入参数
    sum(...numArr);
    sum(...numObj); // :对象不行的:
</script>

image.png

4.2 数组字面量中的扩展运算符

  • 数组的展开会将数组内的元素逐个取出,并按照顺序放置在新的数组中。
  • 数组的展开会在创建一个新的数组。意味着新的数组和原始数组是两个独立的数据对象,它们是不同的引用,对其中一个进行修改不会影响到另一个。
  • 如果展开的元素仍然是数组,则会将其拆分为单独的元素。这意味着,它并不会进行迭代展开
<script>
  const arrOld = [
      [1,1],
      [5,1],
      [12,12]
  ];
  // 3. 如果展开的元素仍然是数组,则会将其拆分为单独的元素。这意味着,它并不会进行迭代展开
  console.log('',...arrOld);

  // 2. 数组的展开会在创建一个新的数组。意味着新的数组和原始数组是两个独立的数据对象,它们是不同的引用,对其中一个进行修改不会影响到另一个。
  const arrNew = [...arrOld];
  arrNew[1] = [12,12];
  // 当然!这里如果对 arrNew[1][1] 进行修改,是会影响到arrOld的。这是容易理解的,故不作解释。
  console.log('old',arrNew);
  console.log('new',arrOld);
</script>

image.png

4.3 对象字面量中的扩展运算符

  • 展开一个对象时,会将对象的属性和属性值复制到新的对象中。
  • 如果展开的对象有相同的属性名,后面的属性值会覆盖前面的属性值。
  • 展开操作只会展开可枚举的自有属性,不会展开原型链上的属性(即使它是可枚举的)。
<script>
  function Person(name,age){
      this.name = name;
      this.age = age;
  }
  // 使用原型对象新增属性 gender
  Person.prototype.gender = 'male';

  // 创建变量
  const person = new Person('ZHK',20);
  console.log('person-- ',person);

  // 使用扩展运算符创建新对象 
  const newPerson = {
      // 2 如果展开的对象有相同的属性名,后面的属性值会覆盖前面的属性值。
      name:'KKK',
      age:18,
      
      // 扩展运算符展开 person对象
      ...person
  };

  // 3 展开操作只会展开可枚举的自有属性,不会展开原型链上的属性(即使它是可枚举的)。
  console.log('newPerson-- ',newPerson);

</script>

image.png

总之,扩展运算符是使用 ... 语法来展开可迭代 数组或对象 的功能。

5. 对象声明简写

简写,即使对象创建时,如果对象属性名和要引入的变量名相同,可以简写一部分。

<script>
  const name = 'ZHK';
  const age = 20;
  const person = {
  
      // name,age 
      // 简写前为 name : name
      name,
      age,
      gender:'male'
  };
  
  console.log(person);
</script>

image.png

6. 箭头函数

箭头函数,这也是一种简写方式。可以和 Java 中的 Lambda 表达式联系记忆。当然,除了均是为了实现更简洁、易读的匿名函数写法之外,它们在语义和语法上也有一些异同。
简单回顾 Java 中的 Lambda 表达式:基本结构为 (参数)->{函数体} 在只有一条表达式的情况下可以使用简化形式省略花括号和return,Lambda 表达式会自动将该表达式的结果作为返回值返回。需要注意,Lambda 表达式只能适用函数式接口(即仅有一个抽象方法的接口)。
ES6 中的箭头函数,基本结构为 参数 => 函数体。要注意它的箭头为 => 勿与Java的Lambda表达式混淆。

  • 箭头函数中,this 指向的是 Window 对象
  • 只有一个参数时,小括号可以省略
<script>
  function Person(name,age){
      this.name = name;
      this.age = age;
  }

  // 1 箭头函数中,this 指向的是 Window 对象
  Person.prototype.selfIntroduce1 = ()=>{
      console.log('这是箭头函数中的this --',this);
  }
  Person.prototype.selfIntroduce2 = function(){
      console.log('这是function的this--',this);
  }

  const person = new Person('k',18);
  person.selfIntroduce1();
  person.selfIntroduce2();

  // 2 只有一个参数时,小括号可以省略
  person.sayHello = name=>console.log(`Hello! My name is ${person.name}`);
  person.ageAddNums = (num1,num2) =>{
      console.log('age加上num1和num2后的值:',person.age + num1+num2);
  }

  person.sayHello();
  person.ageAddNums(1,2);
</script>

image.png