JS ES6 下一代JavaScript语言标准的讲解

Javascript 345 0 2023-01-04

JS ES6 下一代JavaScript语言标准的讲解

ES6简介:

ECMAScript 6.0(以下简称 ES6)是 JavaScript 语言的下一代标准,已经在 2015 年 6 月正式发布了。它的目标,是使得 JavaScript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言。

自ES6的发布后,解决了ES5 的先天不足,ES6新增了很多新特性,提高了开发人员的效率,以下简述ES6都有哪些新特性。


一、先了解下ECMAScript 和 JavaScript 的关系

要讲清楚这个问题,需要回顾历史。1996 年 11 月,JavaScript 的创造者 Netscape 公司,决定将 JavaScript 提交给标准化组织 ECMA,希望这种语言能够成为国际标准。次年,ECMA 发布 262 号标准文件(ECMA-262)的第一版,规定了浏览器脚本语言的标准,并将这种语言称为 ECMAScript,这个版本就是 1.0 版。


该标准从一开始就是针对 JavaScript 语言制定的,但是之所以不叫 JavaScript,有两个原因。一是商标,Java 是 Sun 公司的商标,根据授权协议,只有 Netscape 公司可以合法地使用 JavaScript 这个名字,且 JavaScript 本身也已经被 Netscape 公司注册为商标。二是想体现这门语言的制定者是 ECMA,不是 Netscape,这样有利于保证这门语言的开放性和中立性。


因此,ECMAScript 和 JavaScript 的关系是,前者是后者的规格,后者是前者的一种实现(另外的 ECMAScript 方言还有 JScript 和 ActionScript)。日常场合,这两个词是可以互换的。


二、ES6常用新特性

1、const 和 let

let:局部作用域,(在一对{}启用);不会变量提升;同作用域不能重复声明。

const:同let;声明只读常量,声明时必须初始化赋值。

2、箭头函数

this指向声明时所在的作用域,不能作为构造实例化对象,不能使用arguments变量。

const fn = (a, b) => {
	return a + b 
}
fn(1, 1) // 输出2


3、模板字符串

简化字符串的拼接,模板字符串通过反引号(``)来表示,如果要嵌入变量通过"${变量名}"来实现。

const userInfo = {
  name: 'aliang',
  age: 24,
}
let str = `姓名是:${userInfo.name},年龄是:${userInfo.age}`
console.log(str) // 姓名是:aliang,年龄是:24



4、默认参数

定义:为函数的形参设置默认值;

特点:①简洁;②易读;③便于维护。

function fn(a, b = 'b', c = 'c'){
    console.log(a, b, c);
}
fn('a', 'b1'); // a, b1, c


5、解构赋值

定义:针对数组或者对象进行模式匹配,然后对其中的变量进行赋值;

特点:简洁且易读,语义更加清晰明了;也方便了复杂对象中数据字段获取。

// 数组解构
let [a, b, c] = [1, 2, 3];
console.log(a, b, c) // 1, 2, 3

// 对象解构
let { foo, bar } = { foo: 'aaa', bar: 'bbb' };
console.log(foo, bar) // 'aaa', 'bbb'


6、Promise

Promise是ES6异步编程的一种解决方案,从语法上讲,Promise是一个对象或者说是构造函数,用来封装异步操作并可以获取其成功或失败的结果

promise的状态只能从 未完成->完成, 未完成->失败 且状态不可逆转

1、状态成功(resolve),进入then()得到异步任务的正确结果

2、状态失败(reject),进入catch()获取异常信息

function fn(flag) {
  return new Promise(function (resolve, reject) {
    setTimeout(() => {
      if (flag === true) {
        resolve('promise状态为成功!')
      }
      if (flag === false) {
        reject('promise状态失败!')
      }
    }, 2000)
  })
}

fn(true)
  .then(res => {
    console.log(111111, res) // promise状态为成功!(2秒后执行)
  })
  .catch(err => {
    console.log(222222, err)
  })


7、模块,Import 和 export

定义:

1、export命令:导出模块内部变量、方法等

2、import命令:导入别的模块的变量、方法等,并对其进行使用

特点:

1、在一个文件中,export、import可以有多个,export default仅有一个

2、通过export导出时,导入需要加{};而export default则不需要


例子

1、导出文件(export.js)

export const appId = '11111'
export const appKey = '22222'

export default defaultCity = '杭州'


2、导入文件(import.js)

import defaultCity from './export'
import { appId, appKey } from './export.js'

console.log('defaultCity==>', defaultCity) // 杭州
console.log('appId, appKey==>', appId, appKey) // 11111, 22222

8、class类的基本语法

8.1、class类的基本概念

class写法只是一个语法糖,它只是让对象原型的写法更加清晰,更像面向对象编程的语法

类和模块的内部默认都是严格模式

类不存在变量提升

8.2、constructor 方法

8.2.1、constructor方法是类的默认方法,通过new命令生成对象实例时,自动调用该方法。一个类必须有constructor方法,如果没有显式定义,一个空的constructor方法会被默认添加。

class Point {
}

// 等同于
class Point {
  constructor() {}
}


8.2.2、类的数据类型就是函数,类本身就指向构造函数。

class Point {
  // ...
}

typeof Point // "function"
Point === Point.prototype.constructor // true


8.3、类的实例

class Point {
  // ...
}

// 报错
var point = Point(2, 3);

// 正确
var point = new Point(2, 3);


与 ES5 一样,类的所有实例共享一个原型对象。


var p1 = new Point(2,3);
var p2 = new Point(3,2);

p1.__proto__ === p2.__proto__  // true


8.4、实例属性、静态属性、静态方法

ES6明确规定,Class内部只有静态方法,没有静态属性。

静态属性、静态方法的特点:

①不会被类实例所拥有的属性与方法,只是类自身拥有

②只能通过类调用

ES7有一个静态属性的提案,目前Babel转码器支持。

这个提案对实例属性和静态属性,都规定了新的写法。

8.4.1、类的实例属性

以前实例属性要在构造方法constructor里面定义,而es7中,类的实例属性可以用等式,直接写入类中。

react 中的例子

class ReactCounter extends React.Component {
  // 老写法
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    };
  }
  
  // es7新写法
  state = {
    count: 0
  };
}


8.4.2、类的静态属性

静态属性指的是Class本身的属性,即Class.propname,而不是定义在实例对象(this)上的属性。

// 老写法
class Foo {
}
Foo.prop = 1;

// 新写法
class Foo {
  static prop = 1;
}


8.4.3、类的静态方法

类相当于实例的原型,所有在类中定义的方法,都会被实例继承。如果在一个方法前,加上static关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就称为“静态方法”。

class Foo {
  static classMethod() {
    return 'hello';
  }
}

Foo.classMethod() // 'hello'

var foo = new Foo();
foo.classMethod() // TypeError: foo.classMethod is not a function


8.5、类的继承 extends

class Foo {
  // es7写法,静态属性
  static age = 22
  static classMethod() {
    return 'hello'
  }
  // es7写法,实例属性
  state = {
    name: 'aLiang',
  }

  eatFoo = name => {
    return name
  }
}

class Bar extends Foo {
  // es6写法
  // constructor(props) {
  //   super(props)
  //   this.sex = '男'
  // }

  // es7写法,实例属性
  sex = '男'

  // 静态方法
  static classMethod() {
    return super.classMethod() + ', too'
  }
}

const bar = new Bar()

// 静态属性、静态方法的特点:
// 1.可以被继承
// 2.只能通过类调用,类自身拥有
console.log(Bar.classMethod()) // 'hello, too'
console.log(Bar.age) // 22

// 实例对象,不会访问静态属性、静态方法
console.log(bar.sex) // '男'
console.log(bar.eatFoo('bar')) // 'bar'
console.log(bar.state.name) // 'aLiang'


9、Set与Map


9.1、Set

9.1.1、什么是Set

Set是ES6新增的数据结构,类似数组,但是它的元素成员是唯一的

9.1.2、如何使用,属性和方法

9.1.2.1. 创建Set

① new Set()方式创建

let a = new Set()


② 通过传入数组方式创建

let a = new Set([1, 2, 'aliang'])


9.1.2.2. Set.size:返回Set中元素的数量

let a = new Set([1, 2, 'aliang'])

a.size // 3


9.1.2.3. Set.has(key):查找Set对象中是否存在key,返回一个布尔值

let a = new Set([1, 2, 'aliang'])

a.has('aliang') // true


9.1.2.4. Set.add(key):往Set对象中添加一个元素

let a = new Set()

a.add(1)


9.1.2.5. Set.delete(key):删除元素key

let a = new Set([1, 2, 'aliang'])

a.delete("aliang")


9.1.2.6. Set.clear(): 清空Set的全部元素

let a = new Set([1, 2, 'aliang'])

a.clear()


9.1.2.7. 遍历 Set

① forEach 遍历

let a = new Set([1, 2, 'aliang'])

a.forEach(item => {

 console.log(item)

})


② for of 遍历

let a = new Set([1, 2, 'aliang'])

for(let item of a) {

console.log(item)

}


9.1.2.8. Set 转 数组

① 使用 Array.from 方法

let a = new Set([1, 2, 'aliang'])

let arr = Array.from(a)


② 使用扩展运算符

let a = new Set([1, 2, 'aliang'])

let arr = [...a]


9.1.3、Set的使用场景

可以利用元素成员唯一性,和方法has()是否有某个元素;如实现数组去重等等

代码实现

 // 数组去重
 let arr = [1, 1, 2, 3]
 let unique = [...new Set(arr)] // [1, 2, 3]
 

 let a = new Set([1, 2, 'aliang'])
 let b = new Set([2, 3, 4])

 // 并集
 let union = [...new Set([...a, ...b])] // [1, 2, 'aliang', 3, 4]

 // 交集
 let intersect = [...new Set([...a].filter(item => b.has(item)))] // [2]

 // 差集
 let difference = [
   ...new Set([...a].filter(item => !b.has(item))),
   ...new Set([...b].filter(item => !a.has(item))),
 ] //  [1, 'aliang', 3, 4]



9.2、Map

9.2.1、什么是Map

Map是ES6新增的数据结构,类似于对象,本质上就是键值对的集合,对象的键只能是字符串或者Symbols,但Map的键可以为任意类型


9.2.2、如何使用,属性和方法

9.2.2.1. 创建Map

① new Map()方式创建

let a = new Map()


② 通过传入二维数组方式创建

let kvArray = [

 ['key1', 'value1'],

 ['key2', 'value2'],

]

let a = new Map(kvArray)


9.2.2.2. Map.size:返回Map对象中键值对数量

let kvArray = [

 ['key1', 'value1'],

 ['key2', 'value2'],

]

let a = new Map(kvArray)

a.size // 2


9.2.2.3. Map.has(key):查找Map对象中是否存在key,返回一个布尔值

let kvArray = [

 ['key1', 'value1'],

 ['key2', 'value2'],

]

let a = new Map(kvArray)

a.has('key1') // true


9.2.2.4. Map.set(key, value):设置Map对象的键值对(键名,键值),返回当前对象

let a = new Map()

a.set(0, 'zero')

a.set('key1', 'value1')


9.2.2.5. Map.get(key):返回key值对应的value,如果key不存在则返回undefined

let kvArray = [

 ['key1', 'value1'],

 ['key2', 'value2'],

]

let a = new Map(kvArray)

a.get('key1') // value1


9.2.2.6. Map.delete(key):删除Map对象中键名为key的键值对

let kvArray = [

 ['key1', 'value1'],

 ['key2', 'value2'],

]

let a = new Map(kvArray)

a.delete("key1")


9.2.2.7. Map.clear():移除Map对象中保存的所有键名/键值对

let kvArray = [

 ['key1', 'value1'],

 ['key2', 'value2'],

]

let a = new Map(kvArray)

a.clear()


9.2.2.8. 遍历 Map

① forEach 遍历

let kvArray = [

 ['key1', 'value1'],

 ['key2', 'value2'],

]

let a = new Map(kvArray)


a.forEach((value, key) => {

 console.log(key, value)

})


② for of 遍历

let kvArray = [

 ['key1', 'value1'],

 ['key2', 'value2'],

]

let a = new Map(kvArray)


for (let [key, value] of a) {

 console.log(key, value)

}


9.2.2.9. Map.keys():返回一个新的Iterator对象 它包含按照顺序插入Map对象中每个元素的key值

let kvArray = [

 ['key1', 'value1'],

 ['key2', 'value2'],

]

let a = new Map(kvArray)


for (let key of a.keys()) {

 console.log(key)

}


9.2.2.10. Map.values():返回一个新的Iterator对象 它包含按照顺序插入Map对象中每个元素的value值

let kvArray = [

 ['key1', 'value1'],

 ['key2', 'value2'],

]

let a = new Map(kvArray)


for (let value of a.values()) {

 console.log(value)

}


9.2.2.11. Map.entries():该方法返回一个新的Iterator对象 它包含按顺序插入Map对象中每个[key,value]数组

let kvArray = [

 ['key1', 'value1'],

 ['key2', 'value2'],

]

let a = new Map(kvArray)


for (let [key, value] of a.entries()) {

 console.log(key, value)

}


9.2.2.12. Map 转 数组

① 使用 Array.from 方法

let kvArray = [

 ['key1', 'value1'],

 ['key2', 'value2'],

]

let a = new Map(kvArray)

let arr = Array.from(a)


② 使用扩展运算符

let kvArray = [

 ['key1', 'value1'],

 ['key2', 'value2'],

]

let a = new Map(kvArray)

let arr = [...a]


9.2.3、Map的使用场景

不关心键值对的键名到底是什么,那么在这种情况下,你可以用Map



9.3、Set和Map总结

1、Set:是一组Key的集合,但不存储Value,由于Key不能重复,因此他最大的特点是所有的元素都是唯一的

2、Map:是键值对的集合,为JS带来了真正的键值存储机制;允许任何类型的键,具有极快的查找速度(存储键值较少的情况下)


参考来源:

https://blog.csdn.net/weixin_44246717/article/details/126307776

https://es6.ruanyifeng.com/#README


上一篇:js实现数字位数不足时补零,补左补右自己决定

下一篇:JS实现文字颜色渐变和背景颜色渐变

讨论数量:0

请先登录再发表讨论。 2024-03-29

天涯网魂
3 杠 5 星
TA 的文章
TA 的随言
TA 的资源链