ES6新特性

ES6新特性有哪些

https://www.bilibili.com/video/BV1Hu4y1S7NH/?p=2&spm_id_from=333.880.my_history.page.click&vd_source=5398e6928b40ae5b07f378c8f7f629a4

基本概念

ECMAScript(ES)是 JavaScript 的标准。因为所有主流浏览器都遵循此规范,所以 ECMAScript 和 JavaScript 是可以互换的。

ES5是在2009年定稿发布的JavaScript标准,当前也可以使用es5语法。

ES6是在2015年定稿发布的JavaScript新标准,包括很多强大的功能,这些新特性包括,箭头函数、匿名函数、解构赋值,class类、promise异步编程和export模块导出等等。

 

关键字var、let和const作用域

var 关键字声明变量时,它是全局声明的,如果在函数内部声明则是局部声明的,就叫局部变量。

let 关键字的行为类似var,但有一些额外的功能。 在代码块、语句或表达式中使用 let 关键字声明变量时,其作用域仅限于该代码块、语句或表达式。

const关键字声明常量时,常量值不可更改,且必须初始化常量值。一般用于声明常量

 

【重要】在声明变量或者常量时,最好使用不同的变量名,以避免混淆

【重要】var 、let 和const 的区别

  1. var 声明全局变量或者局部变量,let声明局部变量,const声明常量

  2. var声明全局变量会出现在window对象上,let和const不会

  3. var和let声明的变量可以二次更新值的,const声明的常量则不能修改

  4. var和let声明的变量可以不用赋初始值,任意类型,const声明的常量必须赋初始值

  5. var可以做变量提升,let和const不能

  6. const声明的数组或者对象是可以修改的,但是const声明单个变量是无法修改的

<script>
   // 严格模式
   "use strict"
   // 关键字var、let和const全局变量
   var name = "lisi"
   let gender = "男"
   const age = 20
   
   // var 变量提升
   test = 120
   console.log('变量提升'+ test, window.test);
   var test;

   // 函数内部声明变量,变量仅能在函数内部访问,外部无法访问
   function fn () {
       var name = "赵敏"
       var gender = "女"
       // 常量不能二次赋值
       // age = 30
  }
   fn()
   console.log(name,age, gender);

   // 修改常量值,不能整体赋值,需要单个元素赋值
   const s = [5, 7, 2];
   function editConst() {
       // 使用 s = [2, 5, 7] 将无效
       s[0] = 2
       s[1] = 5
       s[2] = 7
  }
   editConst();
// 对象属性更新
   const obj = {
           name: '李四',
           age: 25
      }
   obj.name = '王五'
   console.log(obj);
</script>

冻结对象,防止属性被更新

const 声明并不会真的保护数据不被改变。 为了确保数据不被改变,JavaScript 提供了一个函数 Object.freeze

<script>
   const data = {
       name: '张三',
       age: 23
  }
   
   // 没加Object.freeze之前可以修改对象属性值
   data.name = "李四"
   console.log(data.name);
   // 加Object.freeze后禁止修改对象属性值
   Object.freeze(data)
   // 修改属性age值失效
   data.age = 30
   console.log(data.age);
</script>

匿名函数

在实际工作中,很多时候不需要写函数名称,且这些函数在其他地方不会复用,此时可以用箭头函数来实现。

<script>
   // 计算总和
   const total = function (a, b) {
       return a + b;
  }
   console.log(total(10, 20));
   // 改成匿名函数
   const getTotal = (a, b) => a + b;
   console.log(getTotal(5, 7));
</script>

箭头函数

和一般的函数一样,你也可以给箭头函数传递参数,如果箭头函数只有一个参数,则可以省略参数外面的括号,如果箭头函数传递多个参数,则括号不能省略。

// 没有参数箭头函数
const fun = () => '无参箭头函数'
console.log(fun());

// 单个参数箭头函数
const fun1 = a => a;
console.log(fun1(1235));

//多个参数箭头函数
const fun2 = (x, y) => x + y;
console.log(fun2(12, 23))

设置函数默认参数

ES6 里允许给函数传入默认参数,来构建更加灵活的函数。

如果不传递参数则使用默认参数值,否则以传入的参数值为准。

const total = (a = 1, b = 1) => a + b;
console.log(total());
console.log(total(10, 8));

rest运算符和函数参数并用

ES6 推出了用于函数参数的 rest 操作符帮助我们创建更加灵活的函数。 rest 操作符可以用于创建有一个变量来接受多个参数的函数。 这些参数被储存在一个可以在函数内部读取的数组中。

const sum = (...args) => {
 let total = 0;
 for (let i = 0; i < args.length; i++) {
   total += args[i];
}
 return total;
}

spread(展开操作符)展开数组项

ES6 引入了展开操作符,可以展开数组以及需要多个参数或元素的表达式。

'use strict'
// 展开操作符接收函数剩余参数
const fun = (a, b, ...values) => {
   // 可以通过typeof判断取到对象或者数组
   console.log(typeof a);
   console.log(a, b, values);
   for (let i = 0; i < values.length; i++) {
       // 取数组
       if (Array.isArray(values[i])) {
           console.log(values[i], '数组');
      }
       // 取对象
       if ((values[i].constructor === Object)) {
           console.log('对象', values[i]);
      }
  }
}
fun(1, 2, 3, 4, 5, { name: '李四'}, [1, 2])
// 展开操作符合并两个数组
const arr = [1, 2]
const arr1 = [3, 4, 5]
const newArr = [...arr, ...arr1]
console.log(newArr);

解构赋值来获取对象的值

解构赋值是 ES6 引入的新语法,用来从数组和对象中提取值,并优雅地对变量进行赋值。当然也可以给解构的值赋予一个新的变量名, 通过在赋值的时候将新的变量名放在冒号后面来实现。

const userInfo = {
   name: '张三',
   age: 23,
   salary: 3200
}
// const name = userInfo.name;
// const salary = userInfo.salary;
// 解构赋值
// const { name, salary } = userInfo
// console.log(name, salary);
// 解构赋值新的别名变量money,原理的salary无法获取值
const { name, salary: money } = userInfo
console.log(name, money);

解构赋值从嵌套对象中分配变量

ES6 允许对象嵌套属性解构展开特性

const userInfo = {
   name: '张三',
   age: 23,
   salary: 3200,
   departMent: {
       name: '产品研发部',
       position: '产品经理'
  }
}
const { departMent: { name: staffName, position } } = userInfo
console.log(staffName, position);

解构赋值将对象作为函数的参数传递

在ES6语法中允许函数的参数里直接解构对象

const userInfo = {
   name: '张三',
   age: 23,
   salary: 3200
}
const fn = ({ name, age, salary }) => {
   console.log(name, age, salary);
}
fn(userInfo)

 

Array解构赋值从数组中分配变量

在 ES6 里面,解构数组可以如同解构对象一样简单。

与数组解构不同,数组的扩展运算会将数组里的所有内容分解成一个由逗号分隔的列表。 所以,你不能选择哪个元素来给变量赋值。

// 使用解构赋值从数组中分配变量
const [a, b] = [1, 2, 3, 4, 5, 6];
const [,,c,, d] = [1, 2, 3, 4, 5, 6];
console.log(a, b);
console.log(c, d);
// 使用rest参数解构数组参数,获取剩余值
const [,, ...arr] = [1, 2, 3, 4, 5, 6]
console.log(arr);
// 数组解构来交换变量
let f = 1, g = 6;
const [g1, f1] = [g, f]
console.log(g1, f1);

模板字面量创建字符串

模板字符串是 ES6 的另外一项新的功能。 这是一种可以轻松构建复杂字符串的方法。

模板字符串可以使用多行字符串和字符串插值功能。

const userInfo = {
   name: '张三',
   age: 23,
   salary: 6200
}
const { name, salary: money } = userInfo
const str = `你好${name},你的工资是${money}元/月`
console.log(str)
// 批量生成模板
const list = ['红楼梦', '西游记', '水浒传', '三国演义']
const UL = document.createElement('ul')
const arr = list.map(m => `<li>${m}</li>`)
UL.innerHTML = arr.reduce((pre, cur) => pre + cur, '')
console.log(UL.innerHTML);
document.body.appendChild(UL)

模板字面量同名属性简写

ES6 添加了一些很棒的功能,用于更方便地定义对象。

ES6 提供了一个语法糖,消除了类似 x: x 这种冗余的写法。 你可以只写一次 x,解释器会自动将其转换成 x: x(或效果相同的内容)

// 简单字段编写简洁的对象字面量声明
const createPerson = (name, age, gender) => {
   return {
       name,
       age,
       gender
  };
};
const person = createPerson("Zodiac Hasbro", 56, "male")
console.log(person);

编写简洁的函数声明

用 ES6 的语法在对象中定义函数的时候,可以删除 function 关键词和冒号。

const userInfo = {
   name: '张三',
   age: 23,
   salary: 6200,
   setSalary(value) {
       this.salary = value;
  }
}
userInfo.setSalary(8000);
const { salary } = userInfo
console.log(salary);

class 语法定义构造函数

ES6 提供了一个新的创建对象的语法,使用关键字 class。

在 ES6 里,class 声明有一个 constructor 方法,与 new 关键字一起被调用。 如果 constructor 方法没有明确定义,那么它就被含蓄地定义为没有参数。

class UserInfo {
   constructor(name) {
    this.name = name
    this.age=23,
  this.salary=6200,
  }
}

const userInfo = new UserInfo('王五');
console.log(userInfo.name); // 应该显示 '王五'

getter 和 setter 来控制对象的访问

你可以从对象中获得一个值,也可以给对象的属性赋值。

这些操作通常被称为 getters 以及 setters。

Getter 函数的作用是可以让对象返回一个私有变量,而不需要直接去访问私有变量。

Setter 函数的作用是可以基于传进的参数来修改对象中私有变量。 这些修改可以是计算,或者是直接替换之前的值。

getter 和 setter 非常重要,因为它们隐藏了内部的实现细节。

class UserInfo {
   constructor (name, age) {
       this._name = name
       this._age = age
       this._salary = 8200
  }
   // getter
   get salary () {
       return this._salary
  }
   // setter
   set salary (salarys) {
       this._salary = salarys
  }
}

const userInfo = new UserInfo('李四', 23)
console.log(userInfo);
// 重置工资
userInfo.salary = 5000
// 获取工资
console.log(userInfo.salary);

export 导出复用代码块

export 可以导出js文件模块,包括数组,对象,方法。

在HTML文件中,要使用es6模块导出,就需要在脚本script上加属性type="module"

准备一个js工具文件tools.js,内容如下

const sum = (a, b) => a + b;

const arrStrToStr = arr => {
   return arr.reduce((pre, cur) => pre + cur, '')
}

export { sum, arrStrToStr }

 

第一种body内部script标签内通过 import xxx from 'xxx.js' 或者 import { xxx } from 'xxx.js' 导入功能模块

<body>
<script type="module">
   import { sum, arrStrToStr } from './scripts/tools.js'
   console.log(sum(1, 3));
   console.log(arrStrToStr(['my', 'name', 'is', 'buyi']));
</script>
</body>

第二种 希望导出tools.js文件所有内容

<script type="module">
   import { sum, arrStrToStr } from './scripts/tools.js'
   // 希望导出tools.js文件所有内容
   import * as Tools from "./scripts/tools.js"
   console.log(Tools.sum(1, 3));
   console.log(Tools.arrStrToStr(['my', 'name', 'is', 'buyi']));
</script>

第三种 导出单文件tools.js

修改tools.js导出方式

【重要】一个js模块不能导出多个默认模块export default

export default sum = (a, b) => a + b;

export default arrStrToStr = arr => {
   return arr.reduce((pre, cur) => pre + cur, '')
}

优化

const total = (a, b) => a + b;
export default total

引入

import total from './scripts/tool.js'
console.log(total(5, 10)); // 应该显示 15

 

Promise异步编程

Promise 是异步编程的一种解决方案 - 它在未来的某时会生成一个值。 任务完成,分执行成功和执行失败两种情况。 Promise 是构造器函数,需要通过 new 关键字来创建。 构造器参数是一个函数,该函数有两个参数 - resolvereject。 通过它们来判断 promise 的执行结果。

语法示例

const myPromise = (a, b) => {
   return new Promise((resolve, reject) => {

  })
}

写一个例子:利用promise计算两个a和b的总和,如果a和b其中一个类型不是number,则抛出错误reject,否则正常返回总和值

const myPromiseToSum = (a, b) => {
   return new Promise((resolve, reject) => {
       if (typeof a ==="number" && typeof b ==="number") {
           resolve({ sum: a + b })
      } else reject('a和b只能是number类型')
  })
}
myPromiseToSum(1, 3).then(res => {
   // 获取resolve结果
   console.log(res);
}).catch(err => {
   // 捕获reject错误
   console.log(err);
})
 
posted @ 2023-07-18 20:20  竹林听雨行  阅读(22)  评论(0编辑  收藏  举报