ES6常用新特性

ES6改动很大,可以简单分为四类
1、解决原有语法的缺陷和不足
例如:let,const
2、对原有语法进行增强
解构、扩展、模板字符串
3、新增对象、全新的方法,全新的功能
Object.assign()、Proxy对象代理、Reflect 等等
4、全新的数据类型和数据结构
set、map、class、迭代器、生成器 等等

一、解决原有语法的缺陷和不足

1、let:块级作用域,没有变量提升

用途:for循环的计数器(for循环内部let声明的变量同样拥有块级作用域);循环事件绑定不必采用闭包形式

for (let i=0; i<3; i++) {
let i = ‘foo’
console.log(i)
}
2、const: 恒量/常量;声明后不能修改内存地址,可修改属性成员

最佳实践:不用var,主用const,配合let

二、对原有语法的增强

1、数组的解构:根据数组对应的位置提取对应的值赋给对应的变量

let arr = [1,2,3]
let [x, y, z] = arr
如果未取到对应的值,赋值“undefined”
可以用…运算符

var [x, …other] = arr
可以设置默认值

var [x=‘0’, y, z] = arr
用途:字符串截取

const str = ‘http://www.baidu.com?titile=article’
var [, strParam] = str.split(‘?’)
2、对象的解构:根据属性名提取

const obj = {name: ‘zdd’, age: 18}
const { name, age } = obj
如果想换一个变量名&添加默认值

const {name: objName=‘www’, age} = obj
应用场景:代码简化

const { log } = console
log(‘hh’)
3、模板字符串:字符串增强

1、可换行
2、可使用插值表达式添加变量,变量也可以替换为可执行的js语句:

let str = 生成一个随机数:${ Math.random() }
标签模板字符串,标签相当于一个自定义函数,自定义函数的第一个参数是被差值表达式截取的数组

// 标签模板字符串
const name = 'www';
const isMan = true
const tagFn = function (strings, name, isMan) {let sex = isMan ? 'man' : 'woman';return strings[0] + name + strings[1] + sex + strings[2]
}
const result = tagFn`hey, ${name} is a ${isMan}.`

4、字符串的扩展方法

1、includes
2、startWith
3、endsWith

5、函数参数增强:参数默认值

只有当参数为不传或传入undefined时使用默认值

const fn = function (x=1, y) {console.log(x)console.log(y)
}
fn()

6、…操作符:收起剩余数据、展开数组

收取剩余参数:取代arguments,arguments是一个类数组,…操作符是一个数组类型,可以使用数组方法
6.1、仅使用一次
6.2、放在参数最后

const fn = function (x, ...y) {console.log(y.slice(0))
}
fn(1,2,3,4,5)

展开数组

const spredArr = [1,2,3,4]
console.log(...spredArr)
console.log.apply(this, spredArr) //es5代替方案

7、箭头函数:简化写法

箭头函数的this指向上级作用域

const name = 'tony'
const person = {name: 'tom',say: () => console.log(this.name),sayHello: function () {console.log(this.name)},sayHi: function () {setTimeout(function () {console.log(this.name)}, 500)},asyncSay: function () {setTimeout(()=>console.log(this.name), 500)}
}
person.say()  //tony
person.sayHello() //tom
person.sayHi() //tony
person.asyncSay()  //tom

8、对象字面量的增强

8.1、如果key与value变量名相同,省略:value
8.2、省略函数:function
8.3、计算属性:[Math.random()]

const bar = ‘bar’
const obj = {
bar,
fn () {
console.log(‘1111’)
},
[Math.random()]: ‘123’
}
console.log(obj)

三、新增对象、全新的方法、全新的功能

1、Object.assign():合并多个对象,第一个参数就是最终的返回值,如果对象的属性名相同,后面的覆盖前面的

用途:复制对象,给options属性赋默认值

let objA = {a: 'aa',b: 'bb'
}
let objB = {b: 'dd',c: 'ee'
}
let result = Object.assign({}, objA, objB)
result.a = 'cc'
console.log(objA, result) //{a: "aa", b: "bb"} {a: "cc", b: "dd", c: "ee"}

2、Object.is():判断两个值是否相等,返回布尔值

用途:es5中,对于0的判断不区分正负值,-0 == +0返回true,NaN == NaN返回 返回false;
Object.is()规避了这些问题

Object.is(+0, -0)//false
Object.is(NaN, NaN) //true

3、Proxy:代理对象

基本用法

const person = {name: 'www',age: '20'
}
const personProxy = new Proxy(person, {get(target, key) {return target[key] ? target[key] : 'default'},set(target, key, value) {target[key] = value % 2 ? value : 99}
})
console.log(person.xxx) // undefined
console.log(personProxy.xxx) // default
console.log(personProxy.age) //20
personProxy.age = 100
console.log(personProxy) //{name: "www", age: 99}

这里注意的一点是,这里被拦截的是”personProxy“,而不是”person“
与Object.definedProperty()的比较:
1、相比与Object.definedProperty只能监听get,set行为,proxy监听的行为更多一些,has、deleteProperty … 等很多
2、对于数组的push,pop等操作,proxy是监听的整个对象的行为,所以通过set方法能够监听到;而definedProperty需要指定该对象的属性名,对于数组来说,就是指定数组的下标,是监听不到数组的push,pop等操作的

let arr = []
let arrProperty = new Proxy(arr, {set (target, key, value) {console.log(target, key, value) //[1] "length" 1target[key] = valuereturn true}
})
arrProperty.push(1)
console.log(arrProperty) //[1]

3、proxy以非侵入的方式,监听了对象的读写;definedProperty需要指定具体需要监听对象的属性名,与上面的数组类似,如果想要监听一个含有多个属性的对象的读写行为,definedProperty需要遍历这个对象的所有属性

4、Reflect: 封装操作对象的统一API

在之前的es5中,操作对象有很多种方式

const obj = {name: '111',age: '22'
}
// 判断对象某个属性是否存在
console.log('name' in obj)
// 删除某个属性
console.log(delete obj['name'])
// 获取对象key
console.log(Object.keys(obj))

对于不同的操作行为,使用的方式却不同,Reflect的目的是使用同一套方式去操作对象

const obj = {name: '111',age: '22'
}
// 判断对象某个属性是否存在
console.log(Reflect.has(obj,'name'))
// 删除某个属性
console.log(Reflect.deleteProperty(obj, 'name'))
// 获取对象key
console.log(Reflect.ownKeys(obj))

5、用于处理异步,解决回调函数的地狱式嵌套问题

四、全新的数据结构和数据类型

1、class 类

es5写法

function People (name) {// 设置实例属性this.name = name;
}
// 设置实例的共享方法
People.prototype.sayHi = function () {console.log(this.name)
}
let p = new People('tom')
p.sayHi()

使用class更易理解,结构清晰

  class Peopel {constructor (name) {this.name = name}say () {console.log(this.name)}}const p = new Peopel('tony')p.say()

类的继承

  class Peopel {constructor (name) {this.name = name}say () {console.log(this.name)   //tom,在子类的sayAge中调用}}class Worker extends Peopel {constructor (name,age) {super(name)this.age = age}sayAge () {super.say()console.log(this)  // Worker {name: "tom", age: 18}console.log(this.age) // 18}}const p = new Worker('tom', 18)p.sayAge()

类的继承还是通过原型链的方式实现,具体可以看下babel转换后的代码
super可以作为函数调用,也可以作为对象调用
作为函数调用时,只能在子类的constructor中调用,此时执行父类的构造函数constructor,执行父类构造函数时,this指向的是子类Worker,所以实例p会有name属性(对于super理解的还是不够,后面要单独学习下)

2、set数据结构:可以理解为集合,不重复

  const s = new Set()s.add(1).add(2).add(3)console.log(s) //{1, 2, 3}console.log(s.size) // 3const arr = [1,2,3,2,4]console.log([... new Set(arr)]) //[1,2,3,4]

3、map数据结构

es5中的对象key只能是字符串,map的key可以是任意数据类型, 可以通过get,set,has等操作map

  const m = new Map()const tom = {name: '99'}m.set(tom, 90)console.log(m.get(tom))m.forEach((value, key) => {console.log(value, key)})

4、Symbol新的数据结构,唯一值

用途:防止全局对象中,某个属性名重名,产生冲突;定义私有属性,外部访问不到,且遍历不到

  const s = Symbol('描述')console.log(s)  const obj = {[Symbol('私有属性')]: '11'}console.log(obj)   //obj对象Symbol('私有属性')这个属性外部访问不到console.log(Object.keys(obj)) //[]console.log(Object.getOwnPropertySymbols(obj)) //[Symbol(私有属性)]const s1 = Symbol.for('111')const s2 = Symbol.for('111')console.log(s1 === s2) //true

5、for … of 遍历

es5中,使用for … in 遍历键值对结构数据,使用forEach遍历数组
es6中新增了set,map数据结构,for…of是用来统一遍历拥有某一种特性的数据结构(可迭代)

  const arr = [1,2,3] for (const item of arr) {// 遍历数组console.log(item)}const s = new Set()s.add(1).add(2).add(3)for (const item of s) {// 遍历set结构console.log(item)}const m = new Map([['name','昵称'],['title', '标题']])for (const [key, value] of m) {// 遍历map结构console.log(key)console.log(value)console.log(m.get(key))}const newSet = new Set([['name','昵称'],['title', '标题']])const newMap = new Map(newSet)for (const [key, val] of newMap) {// 遍历set初始化后的map结构console.log(key)console.log(val)}const obj = {name: 'ttt',age: '19'}for (const [key, val] of obj) {// 遍历对象报错 Uncaught TypeError: obj is not iterableconsole.log(key, val)}

上面代码中,for…of可以遍历数组,set, map,但是却不能遍历对象,是因为对象没有可迭代接口

6、可迭代接口

在浏览器中打印一个数组,在数组的原型对象上有一个Symbol内置属性Symbol.iterator方法,该方法会返回一个iterator对象,该对象包含一个next()方法,调用iterator.next()会返回一个迭代器结果对象iterationResult,iterationResult对象包含两个值,value为遍历的item,done为当前数据是否遍历完成

  const iterator = arr[Symbol.iterator]()console.log(iterator) // Array Iterator {}const ite = iterator.next()console.log(ite) //{value: 1, done: false} value为迭代器的值,done标识是否遍历完

由于上面代码中obj对象不没有Symbol.iterator的内置方法,所以它不是一个可迭代对象,当使用for…of遍历时就报错了,下面手动实现obj可迭代

  let iteratorObj = {//iteratorObj是可迭代对象 iterablename: 'ttww',age: '18',[Symbol.iterator] () {let index = 0;let arr = []for (const key in iteratorObj) {arr.push([key, iteratorObj[key]])}return {//返回的对象叫iteratornext () {return {//结果对象iterationResultvalue: arr[index],done: index++ >= arr.length}},}}}for (const [key, val] of iteratorObj) {console.log(key, val)}

上面代码中,iteratorObj有了可迭代接口,认为是可迭代对象iterable;Symbol.iterator方法返回的对象是迭代器对象iterator;迭代器对象next方法返回的对象是迭代器结果对象iterationResult

6、生成器 generator

用途:处理异步调用回调嵌套的问题

  function *geFn () {console.log('111')yield 100console.log('222')yield 200console.log('333')yield 300}let generator = geFn()console.log(generator.next())  //111 {value: 100, done: false}console.log(generator.next())  //222 {value: 200, done: false}console.log(generator.next())  //333 {value: 300, done: false}

在函数名前面加一个"*",函数就变为生成器函数,执行该函数时,里面的函数不会立即执行,而是会返回一个生成器对象,调用生成器对象的.next方法函数开始执行,当遇到”yield“关键字,函数会停止执行,并把yield的值当做next方法返回对象的value; 当下次调用next方法时,函数从当前位置开始继续执行
生成器函数执行后返回的生成器对象generator,内部也是实现了迭代器接口,所以可以使用for…of来遍历

  function *geFn () {console.log('111')yield 100console.log('222')yield 200console.log('333')yield 300}let generator = geFn()for (const item of generator) {console.log(item)}

可以使用生成器函数改写上面对象的迭代器方法

  let iteratorObj = {name: 'ttww',age: '18',[Symbol.iterator]:function *() {let index = 0;let arr = []for (const key in iteratorObj) {arr.push([key, iteratorObj[key]])}// for (let i =0; i<arr.length; i++) {//   console.log(arr[i])//   yield arr[i]// }for (const item of arr) {yield item}// arr = ['b',3,4,5]// return {//   next () {//     return {//       value: arr[index],//       done: index++ >= arr.length//     }//   },// }}}for (const [key, val] of iteratorObj) {console.log(key, val)}

这里有一个注意的点就是在循环arr数组时,不能是有forEach遍历,是因为forEach里需要传一个回调函数,这个函数不是生成器函数,在非生成器函数里使用yield关键字会报错

ES2016

1、数组新增方法:includes

  const arr = [1,2,3]console.log(arr.includes(2))  //true

2、指数运算符

console.log(2 ** 10) //1024
ES2017

1、Object.values(),以数组的形式,返回对象所有的值

  let obj = {title: 'wwwww',age: 199}console.log(Object.values(obj)) //["wwwww", 199]

2、Object.entries(),以数组的形式,返回对象的所有键值对

let obj = {
title: ‘wwwww’,
age: 199
}
console.log(Object.entries(obj)) //[[“title”, “wwwww”],[“age”, 199]]
可以将对象转为map数据结构

  let obj = {title: 'wwwww',age: 199}let m = new Map(Object.entries(obj))console.log(m) //{"title" => "wwwww", "age" => 199}

3、Object.getOwnPropertyDescriptor()
获取一个对象的完整描述信息,可用于将一个对象的get,set属性赋值给另一个对象

  let obj = {firstName: 'abc',lastName: '123',get fullName () {return this.firstName + this.lastName}}console.log(obj.fullName) //abc123const p2 = Object.assign({}, obj)// 此时赋值给p2的仅仅是fullName属性的值,并没有fullName属性的getterp2.firstName = '456'console.log(p2.fullName)  //abc123const description = Object.getOwnPropertyDescriptors(obj)console.log(description)const p3 = Object.defineProperties({}, description);p3.firstName = '789'console.log(p3.fullName)  //789123

4、字符串的padEnd()、padStart()方法
5、async/await

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/71898.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

手写题目3:算出一个dom里面所有元素的节点数

算出一个dom里面所有元素的节点数 start 获取一个dom元素内的所有节点数。 代码 // 递归函数 function countNodes(node) {// 计算自身var count 1;// 判断是否存在子节点if (node.hasChildNodes()) {// 获取子节点var cnodes node.childNodes;// 对子节点进行递归统…

elasticsearch的索引库操作

索引库就类似数据库表&#xff0c;mapping映射就类似表的结构。我们要向es中存储数据&#xff0c;必须先创建“库”和“表”。 mapping映射属性 mapping是对索引库中文档的约束&#xff0c;常见的mapping属性包括&#xff1a; type&#xff1a;字段数据类型&#xff0c;常见的…

蓝桥杯官网填空题(矩形切割)

题目描述 本题为填空题&#xff0c;只需要算出结果后&#xff0c;在代码中使用输出语句将所填结果输出即可。 小明有一些矩形的材料&#xff0c;他要从这些矩形材料中切割出一些正方形。 当他面对一块矩形材料时&#xff0c;他总是从中间切割一刀&#xff0c;切出一块最大的…

[论文笔记]A COMPARE-AGGREGATE MODEL FOR MATCHING TEXT SEQUENCES

引言 今天带来论文A COMPARE-AGGREGATE MODEL FOR MATCHING TEXT SEQUENCES的阅读笔记。 很多NLP任务,包括阅读理解、文本蕴含和问答任务,都需要在序列之间进行比较。匹配序列间重要的单位是这些解决这些任务的关键。本篇工作提出了一个通用的比较聚合(compare-aggragate)框…

Docker Compose常用命令

常用命令 1.1 restart, start, stop-- 启动和停止服务 命令必须在 docker-compose.yml文件所在的目录下执行。 # 前台启动, 启动项目中的所有服务。 $. docker-compose up# 后台启动, 启动所有服务并在后台运行。 $. docker-compose up -d# 停止所有服务。 $. docker-compose …

大数据课程K18——Spark的ALS算法与显式矩阵分解

文章作者邮箱:yugongshiye@sina.cn 地址:广东惠州 ▲ 本章节目的 ⚪ 掌握Spark的ALS算法与显式矩阵分解; ⚪ 掌握Spark的ALS算法原理; 一、ALS算法与显式矩阵分解 1. 概述 我们在实现推荐系统时,当要处理的那些数据是由用户所提供的自身的偏好数据,这些…

什么是机器学习中的监督学习和无监督学习,举例说明

1、什么是机器学习中的监督学习和无监督学习&#xff0c;举例说明。 监督学习&#xff1a; 监督学习是一种机器学习的方法&#xff0c;它通过已知的数据&#xff08;即训练数据&#xff09;来预测未知的数据&#xff08;即测试数据&#xff09;。例如&#xff0c;一个监督学习…

k8s node环境部署(三)

1、添加node1、node2环境 前面配置master环境的截图最后一段 复制下来 分别在node主机执行 kubeadm join 192.168.37.132:6443 --token p5omh3.cqjqt8ymrwkdn2fc \ --discovery-token-ca-cert-hash sha256:608a1cbadd060cfdeac2fae84c19609061b750ab51bf9a19887ff7ea…

Ubuntu之apt-get系列--安装JDK8--方法/教程

原文网址&#xff1a;Ubuntu之apt-get系列--安装JDK8--方法/教程_IT利刃出鞘的博客 简介 本文介绍如何在Ubuntu下安装JDK8。 验证是否安装 可以通过如下命令判断系统是否有安装ssh服务&#xff1a; 命令 java -version 结果 如上所示&#xff0c;表示还没有安装。 查看…

实训三:多表查询 - 大学数据库创建与查询实战

大学数据库创建与查询实战 第1关&#xff1a;数据库表设计任务描述相关知识大学数据库的整体设计教师信息表&#xff08;instructor&#xff09;开课信息表&#xff08;section&#xff09; 编程要求测试说明参考代码 第2关&#xff1a;查询&#xff08;一&#xff09;任务描述…

从零开始学习软件测试-第38天笔记

接口测试 什么是接口 接口是两个独立部件共享信息的边界&#xff0c;测试中常说的接口大部分是web接口。web接口是遵循了http或者https协议的URL。 数据的流转过程 由客户端通过接口将数据发送给服务器。服务器收到数据之后&#xff0c;取出想要的数据&#xff0c;拼装成一…

[虚幻引擎插件介绍] DTGlobalEvent 蓝图全局事件, Actor, UMG 相互回调,自由回调通知事件函数,支持自定义参数。

本插件可以在虚幻的蓝图 Actor&#xff0c; Obiect&#xff0c;UMG 里面指定绑定和执行消息&#xff0c;可带自定义参数。 参数支持 Bool&#xff0c;Byte&#xff0c;Int&#xff0c;Int64&#xff0c;Float&#xff0c;Name&#xff0c;String&#xff0c;Text&#xff0c;Ve…

Ubuntu 20.04 LTS 安装Kubernetes 1.26

1、环境配置 (1)添加主机名称解析记录 cat > /etc/hosts << EOF 192.168.44.200 master01 master01.bypass.cn 192.168.44.201 node01 node01.bypass.cn 192.168.44.202 node02 node02.bypass.cn EOF(2)禁止K8s使用虚拟内存 swapoff -a sed -ri s(.*swap.*)#\1…

常见关系型数据库SQL增删改查语句

常见关系型数据库SQL增删改查语句&#xff1a; 创建表&#xff08;Create Table&#xff09;&#xff1a; CREATE TABLE employees (id INT PRIMARY KEY,name VARCHAR(50),age INT,department VARCHAR(50) ); 插入数据&#xff08;Insert Into&#xff09;&#xff1a; INSERT …

sqlite3 是一个命令行工具,用于与 SQLite 数据库进行交互和管理

通过在终端或命令提示符中键入 sqlite3 命令&#xff0c;可以启动 sqlite3 工具并连接到指定的 SQLite 数据库文件。 连接成功后&#xff0c;你将获得一个交互式的命令行界面&#xff0c;可以在其中执行各种数据库操作。使用 sqlite3 命令时&#xff0c;可以提供以下参数&#…

自然语言处理:提取长文本进行文本主要内容(文本意思)概括 (两种方法,但效果都一般)

本文主要针对长文本进行文本提取和中心思想概括&#xff0c;原文档放在了附件里面&#xff1a;<科大讯飞公告> -----------------------------------方法一&#xff1a;jieba分词提取文本&#xff08;句子赋分法&#xff09;------------------------- 1、首先导入相关…

【车载开发系列】诊断故障码中的扩展数据

【车载开发系列】诊断故障码中的扩展数据 诊断故障码中的扩展数据 【车载开发系列】诊断故障码中的扩展数据一. 扩展数据概念二. DemDataElementClass对象三. DemInternalDataElement对象四. DemExtendedDataClass五. DemExtendedDataRecordClass1)DemExtendedDataRecordNumbe…

【Cicadaplayer】avpkt 队列(mPacketQueue)的条件等待(wait)

此时,网络包读取,网络包可能有音频、视频、字幕等等。MAX_QUEUE_SIZE 是总共的包数目的上限,保证mPacketQueue 不能太大也不能太小。小于此值,读取线程会等待。std::condition_variable.wait()的用法和设计缺陷带来的坑 大神对条件变量做了深入分析。int avFormatDemuxer::…

go基础09-Go语言的字符串类型

字符串类型是现代编程语言中最常使用的数据类型之一。在Go语言的先祖之一C语言当中&#xff0c;字符串类型并没有被显式定义&#xff0c;而是以字符串字面值常量或以’\0’结尾的字符类型&#xff08;char&#xff09;数组来呈现的&#xff1a; #define GOAUTHERS "Rober…

vue3 defineProps 函数

在 vue2 中我们使用选项中的 props 来接受父组件传递过来的数据&#xff1b;那在 vue3 的 setup 中&#xff0c;我们使用 defineProps 来定义父组件传递过来的数据 1、defineProps 支持的类型有&#xff1a;String、Number、Boolean、Object、Array、Function&#xff0c;除此之…