【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:生成器函数完成
相关推荐
m0_607548762 分钟前
什么是单例模式
开发语言·javascript·单例模式
半糖11229 分钟前
将本地项目提交到远程仓库
前端·vue.js
web150850966414 小时前
【React&前端】大屏适配解决方案&从框架结构到实现(超详细)(附代码)
前端·react.js·前端框架
理想不理想v4 小时前
前端项目性能优化(详细)
前端·性能优化
CodeToGym4 小时前
使用 Vite 和 Redux Toolkit 创建 React 项目
前端·javascript·react.js·redux
Cachel wood5 小时前
Vue.js前端框架教程8:Vue消息提示ElMessage和ElMessageBox
linux·前端·javascript·vue.js·前端框架·ecmascript
PP东6 小时前
ES6学习Generator 函数(生成器)(八)
javascript·学习·es6
桃园码工7 小时前
4_使用 HTML5 Canvas API (3) --[HTML5 API 学习之旅]
前端·html5·canvas
桃园码工7 小时前
9_HTML5 SVG (5) --[HTML5 API 学习之旅]
前端·html5·svg
人才程序员7 小时前
QML z轴(z-order)前后层级
c语言·前端·c++·qt·软件工程·用户界面·界面