【JS】ES6

什么是ES6?理解es6首先需要理解三个概念:JavaScript:分为ECMAScript(核心),DOM,BOM;ECMA-262:ECMA的第262条标准就是ECMAScript;ECMA:国际标准化组织机构(欧洲计算机制造商协会)。ECMAScript:是脚本语言的标准化规范。命名历史:Mocha(网景) --> LiveScript --> JavaScript(升阳+网景)

对象

es6之前写对象

javascript 复制代码
let obj={
	a:1,
	show:function () {}
}

es6对象

javascript 复制代码
let a=1;
let fn=function () {}
let obj2={
	a,  //等同于:键名a的值是变量a,不用按照键值对的方式去写
	fn,
	show(){

	}
}
console.log(obj2.a) // 1

Object.assign(被合并的对象,合并用的模板,......) 对象的合并 => 可以用扩展运算符(...)替代

javascript 复制代码
let json1={a:1};
let json2={b:1};
let json3={c:1,a:9};
console.log(Object.assign(json1,json2,json3)) //扩充到了第一个参数上;如果属性重叠,后面的会覆盖前面的
console.log(json1,json2,json3) // {a: 9, b: 1, c: 1} {b: 1} {c: 1, a: 9}
console.log({
	...json1,
	...json2,
	...json3
}) // {a: 9, b: 1, c: 1} {b: 1} {c: 1, a: 9}


//也可以用作数组合并(这样的合并没啥用)
let arr=[0,1,2];
let arr2=[3,4];
console.log(Object.assign(arr,arr2)); // [3,4,2]对应的下标合并对应的下标

Object.is() 判断两个内容是否相同

javascript 复制代码
console.log(Object.is("aaa","aaa")) // true

Symbol

新增的基本数据类型:Symbol;它的产生是通过Symbol函数,它可以接收一个字符串作为参数,表示对Symbol实例的描述,为了在控制台显示或者转为字符串时做区分。ES6之前:对象属性名都是字符串,非常容易重复属性名,Symbol保证每个属性的名字都是独一无二的数据类型:Undefined;Null;Boolean;String;Number;Object( 包含Array和Function );Symbol

javascript 复制代码
let s1=Symbol("s1");
let s2=Symbol("s2");
console.log(s1==s2) // false 因为每个值都是独一无二的

console.log(s1,s2) // Symbol(s1) Symbol(s2)
console.log(s1.description,s2.description) // s1 s2 把传递进去的字符串提取出来
javascript 复制代码
//Symbol使用在对象上
let obj={
	"a":1,
}
let json={
	[s1]:1, //这个属性就变成了唯一值
}
json[s2]=2; //对象的属性可以用[]取来用,[]中的是变量不是字符串
console.log(json[s2]) // 2

Symbol作为属性名,遍历对象的时候,该属性不会出现在for in、for of循环中;也不会被 Object.keys()、Object.getOwnPropertyName()、JSON.stringify返回

javascript 复制代码
let obj2={
	name:"月月",
	age:24,
	sex:"女"
}
for(let i in obj2){
	console.log(i)  //name age sex
	console.log(obj2[i])  //月月 24 女
}
for(let i in json){  //无法遍历出来
	console.log(i)
	console.log(json[i])
}

Set

es6新的数据结构,常用 set 和 map。set:它类似于数组,但是成员的值是唯一的,没有重复的值,可以简单理解为它是一个没有重复值的数组;方法: add():向set结构添加成员;delete(value):删除某个值,返回一个布尔值,表示删除是否成功;has(value):返回一个布尔值,表示该值是否为set成员;clear():清除所有成员,没有返回值。将set结构变成真正的数组[...set]

语法

javascript 复制代码
let s=new Set();
console.log(s)  //{}

添加

javascript 复制代码
s.add(1)
s.add(2)
s.add(3)
s.add(2) //不能写重复的值,写进去也会过滤掉
console.log(s) //{1, 2, 3}

let s2=new Set([1,2,3,4,5,6]); //初始化数据
console.log(s2) //{1, 2, 3, 4, 5, 6}

删除

javascript 复制代码
s2.delete(1)
console.log(s2) //{2, 3, 4, 5, 6}

包含

javascript 复制代码
console.log(s2.has(1)) //false

清除

javascript 复制代码
s2.clear();
console.log(s2) //{}

size类似数组的长度

javascript 复制代码
console.log(s2.size)  //0

将set变成数组

javascript 复制代码
console.log([...s])  //[1, 2, 3]

将set变成数组 => Array.from()方法可以将一个类数组对象或者可遍历对象转换为一个真正的数组(es6新增语法)( 类数组对象?最基本的要求就是具有length属性的对象 )

javascript 复制代码
let arrObj={
	0:"月月",
	1:"女",
	2:"18",
	3:["吃饭","睡觉","打豆豆"],
	"length":4
}
console.log(arrObj) //{0: '月月', 1: '女', 2: '18', 3: Array(3), length: 4}

let myArr=Array.from(arrObj)
console.log(myArr) //['月月', '女', '18', Array(3)]

由于set没有重复的特性,可以用它来做数组的去重

javascript 复制代码
let testArray=[1,1,2,3,2,66,3,66,8,2,66,1]

let t1=new Set(testArray)
console.log(t1) //{1, 2, 3, 66, 8}

let result=[...t1]  //把利用set去重后的数组(set结构)转回数组结构
console.log(result) //[1, 2, 3, 66, 8]

Set数据结构的遍历

javascript 复制代码
let s4=new Set(["a","b","c","d"])

for(let i in s4){ //错误方法
	console.log(s4[i])  //打不出任何东西
}

s4.forEach((item,index)=>{ //正确方法:可以取到值,但是取不到下标
	console.log(item)  //a b c d
	console.log(index) //a b c d
})

for(let i of s4){ //可以取到值,但是取不到下标
	console.log(i) //a b c d
}

//for...of循环可以选择遍历值value,遍历keys,遍历键值对entries
for(let i of s4.values()){
	console.log(i) //a b c d
}
for(let i of s4.keys()){
	console.log(i) //a b c d
}
for(let i of s4.entries()){ //set结构是花括号对象的形式
	console.log(i) //['a', 'a'] ['b', 'b'] ['c', 'c'] ['d', 'd']
}

Map

数据结构:map可以是任何数据类型的对象。创建:new Map();方法:set()get()has()delete()size()clear()

创建

javascript 复制代码
let m=new Map()
console.log(m)  //{}

添加

javascript 复制代码
const o={
	n:"月月"
}
m.set(o,"myContent")
console.log(m)  //{{...} => 'myContent'}
m.set("name","快乐")

获取

javascript 复制代码
console.log(m.get(o))  //myContent
console.log(m.get("name"))  //快乐

包含

javascript 复制代码
console.log(m.has(o)) //true

删除

javascript 复制代码
m.delete(o)
console.log(m) //{'name' => '快乐'}

size

javascript 复制代码
console.log(m.size)  //1

清空

javascript 复制代码
m.clear()
console.log(m)  //{}

遍历,同set一样

javascript 复制代码
const m2=new Map();
m2.set("name1","小仙女");
m2.set("name2","神仙姐姐");
m2.set("name3","刘亦菲");

//注意:map中set值的时候键名不能重复,重复会造成覆盖
console.log(m2)  //{'name1' => '小仙女', 'name2' => '神仙姐姐', 'name3' => '刘亦菲'}

/*m2.forEach((value, key, map)=>{
	console.log(value) //值
	console.log(key) //name1
	console.log(map) //当前的m2
})*/

//for...of循环可以选择遍历值value,遍历keys,遍历键值对entries
for(let i of m2.entries()){
	console.log(i) //['name1', '小仙女'] ['name2', '神仙姐姐'] ['name3', '刘亦菲']
}

模块化

es6的模块化

javascript 复制代码
1.必须放在服务器的环境中
2.import 'xxx' 直接写路径相当于引入了文件
3.关于路径,可以写相对路径,也可以写绝对路径
4.多次引入相同的模块,只相当于引入了一次
5.引入模块的时候,就会预加载提升到开头
6.模块化的写法必须是严格模式,es6所有都是严格模式

es6模块化的好处

javascript 复制代码
1.一个模块就是一个js文件
2.可以按照需求来加载
3.模块小,便于维护,减小冗余
4.每个模块都有自己的作用域,变量都是私有的

1.a.js 文件

javascript 复制代码
//一个对象,一个函数,或者是一个变量都可以当做一个模块

/*
let a=1;
let b=2;
export {a,b}
*/

/*
export let a=1;
export let b=2;
*/

let a=1;
let b=2;
// export {a as aa,b as bb} //这里不能将别名加引号

export default {a,b}

另外的文件中引入使用

html 复制代码
<script type="module">//报错:Cannot use import statement outside a module(解决方法:type="module")
	// import './1.a.js'  //引入的是一整个js文件

	// import {a,b} from './1.a.js'

	// import {aa,bb} from './1.a.js'

	// import {aa as a,bb as b} from './1.a.js'

	//整体引入模块
	// import * as mod from './1.a.js'

	import ('./1.a.js')  //动态引入;返回一个Promise对象
		.then(res=>{
			console.log(res)
		})

	// console.log(mod.aa,mod.bb)

</script>

总结:模块的导出引入

javascript 复制代码
export {a}
import './1.a.js'  //引入的是一整个js文件

export {a,b}
import {a,b} from './1.a.js'  //将导出的模块解构到当前页面(引入的是导出的内容)

export let a=1;
export let b=2;
import {a,b} from './1.a.js'

export {a as aa,b as bb}   //导出起别名
import {aa,bb} from './1.a.js'

import {aa as a,bb as b} from './1.a.js'  //引入起别名

import * as mod from './1.a.js'  //整体引入模块
console.log(mod.aa,mod.bb)

vue中导出的时候通常都是export default{} 与 export有什么区别?

javascript 复制代码
1. 一个文件中export可以有多个,export default只能有一个

2. export暴露的是一个接口,在 import 时不能改变它的变量名,并且必须加上大括号{}
			export var a = 1;  =>  import { a } from xx.js

3. export default暴露的是一个变量,在import时可以使用任意变量名导入,不用加大括号{}
			var a = 1; export default a;  =>  import anyName from xx.js

解构赋值

javascript 复制代码
// let a=1;
// let b=2;
// let c=3;
let [a,b,c]=[1,2,3];
console.log(a,b,c) //1 2 3


let [foo,[[a1,a2],[b1]]]=[1,[[2,8],[3]]]  //不管多复杂跟着结构对对应的值就行(只要两边结构对上,赋值就能成功)
console.log(foo,a1,a2,b1)  //1 2 8 3


let [foo1]=[];
console.log(foo1) //undefined


let [a3,a4]=[5]
console.log(a3,a4) //5 undefined


//不完全解构
let [x,y]=[1,2,3]
console.log(x,y)  //1 2


let [a5,[b2],d]=[1,[2,3],4]
console.log(a5,b2,d) //1 2 4


//如果等号的右边不是数组,严格来说就是不可遍历的结构都会报错
// let [foo2]=1;
// let [foo2]=false;
// let [foo2]=NaN;
// let [foo2]=undefined;
// let [foo2]=null;
// let [foo2]= {};
// console.log(foo2) //报错,两边类型结构不一样


const [a7,b7,c7,d7,e7]="hello"
console.log(a7,b7,c7,d7,e7)  //h e l l o


//对象的解构赋值(通过键名去对应的)
let {bar:a6}={foo3:"aaa",bar:"bbb"}
console.log(a6)  //bbb

箭头函数

javascript 复制代码
function fName(n) {
	//函数体
}

let myF=function () {
	//函数体
}


//数组的find方法:用于找出第一个符合条件的数组成员
//它的参数是一个函数,所有数组成员依次执行该回调函数,直到找出第一个返回值为true的成员,然后返回该成员,如果没有符合条件的成员,则返回undefined
let myNo=[1,4,5,-5,10].find(function (n){
	if(n<0){
		return n;
	}
})
console.log(myNo) //-5


//用箭头函数
let myNo2=[1,4,5,-5,10].find(n=>n<0)
console.log(myNo2) //-5


let myFun=(n,m)=>{
	console.log(n+m)
}
myFun(1,2) //3

扩展运算符

... 扩展运算符(rest运算符)

javascript 复制代码
//可以将一个数组转为用逗号分隔的参数序列,解构赋值可以和扩展运算符一起使用
let [header,...tail]=[1,2,3,4,5] //rest运算符只能放在最后
console.log(header,tail) //1 [2,3,4,5]


let myArr=[1,2,3];
console.log(...myArr) //1 2 3
console.log(0,...myArr) //0 1 2 3


//扩展运算符用于函数调用
function add(x, y) {
	return x+y;
}
let myResult=add(5,6); //普通调用函数
console.log(myResult) //11


let numbers=[7,9];
myResult=add(...numbers); //使用扩展运算符调用函数
console.log(myResult) //16


function myPush(arr,item) {
	arr.push(...item); //在数组中使用
	return arr;
}
let myArr2=[];
let newArr=myPush(myArr2,[1,2,3,4,5])
console.log(newArr) //[1, 2, 3, 4, 5]


function f(v, w, x, y, z) {
	console.log(v,w,x,y,z) //-1 0 1 '哈哈' '可以'
}
const args=[0,1]
f(-1,...args,"哈哈","可以"); //可以混合着写


let x=3;
const arr=[
	...(x>0?['a','c']:[]), //配合三元运算符使用
	"b",
]
console.log(arr) //['a', 'c', 'b']


console.log(Math.max(...[11,23,10,5])) //23


let arr1=[0,1,2];
let arr2=[3,4,5];
arr1.push(...arr2)
console.log(arr1) //[0, 1, 2, 3, 4, 5]


const a3=[1,2];
// let a4=a3; //不能这么赋值,它们通过堆栈指向同一个数组
let a4=[...a3];
console.log(a4) //[1, 2]

async 异步

async 用于申明一个function是异步的,会结合await使用;await 用于等待一个异步方法执行完成;和 Promise有很大关联

javascript 复制代码
async function testAsync(){
	return "hello Async"
}

const result=testAsync();
console.log(result) //async函数会返回一个Promise对象,可以使用then方法添加回调函数


async function thenAsync(){
	return "then Async"
}

thenAsync().then((v)=>{
	console.log(v)
})

async函数中使用await表达式;async函数执行时,如果遇到await会先暂停执行,等到触发的异步操作执行完成后,恢复async函数的执行并返回解析值;await关键字,仅仅在async函数中有效,在async函数外使用await只会报错

javascript 复制代码
async function testAwait(){
	return new Promise((resolve)=>{
		setTimeout(()=>{
			console.log("test Await")
			resolve()
		},2000)
	})
}

async function awaitAsync(){
	await testAwait()
	console.log("await Async")
}

awaitAsync();

一般来说都认为await是在等待一个async函数执行完成;它可以等待任意表达式的结果;await后面实际上可以接普通函数的调用或者直接量

javascript 复制代码
function getSomething(){
	console.log("777")
	return "getSomething"
}

async function testAsync2(){
	console.log("666")
	return Promise.resolve("testAsync2")
}

async function test(){
	const v1= await getSomething();
	const v2=await testAsync2();
	console.log(v1,v2)
}

test();

filter 过滤

过滤、筛选,调用filter之后会返回过滤后的新数组。filter的回调函数(callback())需要返回一个布尔值;true表示通过筛选,将会被返回,false则筛选不通过,不会在新数组中返回

javascript 复制代码
let arr=[1,2,3,4,5,6]
let newArr=arr.filter(item=>item>5)
console.log(newArr) //[6]

newArr=arr.filter(function (item) {
	return item>5;
})

filter()去掉数组重复元素,结合数组的indexOf()方法;indexOf():可返回数组中某个指定的元素位置,从头到尾检索数组,看它是否有对应元素

javascript 复制代码
let arr2=["hello","world","singleDog","hello","nice","apple","apple"]
let newArr2=arr2.filter(function (element,index,self){
	// console.log(self)
	console.log(self.indexOf(element)) //元素第一次出现的位置

	return self.indexOf(element)===index; //去重
})
console.log(newArr2)

过滤包含"2"的数字;搭配String.indexOf()使用,如果字符串item包含字符就返回字符的位置,如果item不包含字符则返回-1

javascript 复制代码
let arr3=['10','12','13','22','14']
// let newArr3=arr3.filter(item=>item.indexOf('2')<0)
newArr3=arr3.filter(function (item) {
	console.log(item)
	console.log(item.indexOf('2'))
	return item.indexOf('2')==-1;
})
console.log(newArr3)

yield 关键字

yield是es6新的关键字,用来暂停和回复一个生成器函数( function* )。参考内容:https://www.jianshu.com/p/7635227a46bd

javascript 复制代码
function* countAppleSales() {
	let saleList=[3,5,7];
	for(let i=0;i<saleList.length;i++){
		yield saleList[i]; //不会自动执行,需要next()才会执行
	}
}

let appleStore=countAppleSales();
console.log(appleStore)
console.log(appleStore.next())
console.log(appleStore.next())
console.log(appleStore.next()) //7  false:生成器函数没有完成
console.log(appleStore.next()) //undefined  true:生成器函数完成
相关推荐
腾讯TNTWeb前端团队44 分钟前
helux v5 发布了,像pinia一样优雅地管理你的react状态吧
前端·javascript·react.js
范文杰4 小时前
AI 时代如何更高效开发前端组件?21st.dev 给了一种答案
前端·ai编程
拉不动的猪4 小时前
刷刷题50(常见的js数据通信与渲染问题)
前端·javascript·面试
拉不动的猪4 小时前
JS多线程Webworks中的几种实战场景演示
前端·javascript·面试
FreeCultureBoy5 小时前
macOS 命令行 原生挂载 webdav 方法
前端
uhakadotcom6 小时前
Astro 框架:快速构建内容驱动型网站的利器
前端·javascript·面试
uhakadotcom6 小时前
了解Nest.js和Next.js:如何选择合适的框架
前端·javascript·面试
uhakadotcom6 小时前
React与Next.js:基础知识及应用场景
前端·面试·github
uhakadotcom6 小时前
Remix 框架:性能与易用性的完美结合
前端·javascript·面试
uhakadotcom6 小时前
Node.js 包管理器:npm vs pnpm
前端·javascript·面试