文章目录
一、let和const
let:定义变量,只能在块作用域里访问,不能声明同名变量。不存在变量提升的问题
const:定义常量,不能声明同名变量,只能在块作用域里访问,而且不能修改,但是在定义的对象时对象属性值可以改变,不存在变量提升的问题
二、Symbol
用于表示一个独一无二的值,不能与其他数据类型进行运算。它是JavaScript中的第七种数据类型,与undefined、null、Number(数值)、String(字符串)、Boolean(布尔值)、Object(对象)并列,是基本数据类型
//这样创建一个Symbol值
const newValue = Symbol();//或者使用let创建
let newValue = Symbol();
console.log(newValue ); //Symbol()
//因为Symbol是基本数据类型,而不是对象所以不能用 new 创建,
//会出现Symbol is not a constructor的报错
const newValue = new Symbol();
三、模板字符串
3.1 什么是模板字符串
在模板字符串没出现之前,处理字符串:通过“\”和“+”来构建模板,非常的麻烦并且很容易漏写符号,对ES6的模板字符串出现后,用${``}可以直接实现,非常方便;
let arr = '我是字符串'
let html = `<div>
文字文字<span>${arr}</span>
</div>`
3.2 字符串新方法
1、includes():判断字符串是否包含参数字符串,返回boolean值。
let str = 'apple,orange,banana';
str.includes('apple');//true
2、startsWith() / endsWith():判断字符串是否以参数字符串开头或结尾。返回boolean值。这两个方法可以有第二个参数,一个数字,表示开始查找的位置。
let str = 'apple,orange,banana';
str.startsWith('apple');//true
str.endsWith('peach');//false
3、repeat():方法按指定次数返回一个新的字符串
let a='hi'
console.log('hello'.repeat(2)); //'hihi'
4、padStart()/padEnd():用参数字符串按给定长度从前面或后面补全字符串,返回新字符串。
let arr='app'
console.log(arr.padEnd(4,'l'));//appl
console.log(arr.padEnd(6)); //'app '如果没有传入值将用空格代替
console.log(arr.padStart(5,'o')); //ooapp
四、解构表达式
4.1 数组解构
ES6允许按照一定模式,从数组或者对象中提取值,对变量进行赋值,这被称为解构。
解构的作用是可以快速取得对象当中的元素或属性,无需再用arr[x]或者obj[key]传统的方式进行赋值
let arr=[1,2,3]
let [a,b,c] =arr
console.log(a,b,c); //1,2,3
let arr=[1,2[3,4]];
let [a,b[c,d]]=arr
console.log(a,b,c,d)//1,2,3,4
let arr=[1,2,];
let [a,b,c]=arr
console.log(a,b,c); //1,2,undefined
//...是剩余运算符,表示赋值运算符右边除第一个值外剩余的都赋值给b
let arr=[1,2,3]
let [a,..b] = arr;
console.log(a,b);//1,[2,3]
4.2 对象解构
需要注意的点是变量名和属性都可以修改,但是必须相同
let obj = {
name: "张三",
age: 12,
sex: "man"
};
let { name, age, sex } = obj;
//或者(想解构哪个变量就把哪个变量写进去)
let { name, age, sex } = {
name: "张三",
age: 10,
sex: "man"
};
//都能打印出以下结果
console.log(name, age, sex); //'张三' 10 'man'
//错误写法 name1和name变量名不同,是打印不出来的
let obj = {
name1: "张三",
age: 10,
sex: "man"
};
let { name, age, sex } = obj;
五、Set()、map()数据结构
5.1 map()是什么及写法?
5.1.1 map()是什么及写法?
map属于es6新增加的数据结构,map()是键值对,里面的键和值可以任意,Map对象有一个size属性,存储了键值对的个数,而object对象没有类似属性。
let newMap = new Map([['name','zhangsan'],['age',10]]);
console.log(newMap ); //{'name'=>'zhangsan','age'=>10}
5.1.2 map()下的内置方法:
map.set(key,value):设置键名key对应的键值value,返回整个map解构,如果key已经有值,则进行覆盖,可以链式操作
let newMap = new Map([
["name", "zhangsan"],
["age", 10],
]);
newMap.set("sex", "man");
console.log(newMap); //{'name' => 'zhangsan', 'age' => 10, 'sex' => 'man'}
newMap.set("name", "lisi");
console.log(newMap); // {'name' => 'lisi', 'age' => 10, 'sex' => 'man'}
newMap.set("sex", "man").set("aaa", "hahah");
console.log(newMap); // {'name' => 'lisi', 'age' => 10, 'sex' => 'man', 'aaa' => 'hahah'}
map.get(value):get方法读取key对应的键值,如果找不到就返回underfined
let newMap = new Map([
["name", "zhangsan"],
["age", 10],
]);
console.log(newMap.get("age")); //10
console.log(newMap.get("ages")); //undefined
map.has(value):判断该值是否为met成员,返回一个布尔值
let newMap = new Map([
["name", "zhangsan"],
["age", 10],
]);
console.log(newMap.has("aaa")); //false
console.log(newMap.has("name")); //true
console.log(newMap); //{'name' => 'zhangsan', 'age' => 10}
map.clear():清除所有数据,没有返回值
let newMap = new Map([
["name", "zhangsan"],
["age", 10],
]);
newMap.clear();
console.log(newMap); // {size: 0}
map.entries():返回键值对的遍历器
let newMap = new Map([
["name", "zhangsan"],
["age", 10],
]);
newMap.entries();
console.log(newMap); //{'name' => 'zhangsan', 'age' => 10}
5.2 Set()
5.2.1 Set()是什么及写法?
Set()是值的集合,是类数组,里面的值的唯一的,可以实现数组去重
//注意:必须传数组进去,否则会报错
let newSet = new Set([1,2,3]);
console.log(newSet ); //{1,2,3}
5.2.2 Set()下的内置方法:
Set.add(value):添加一个数据,返回Set解构本身,可以进行链式操作
let newSet = new Set([1, 2, 3]);
newSet.add(4)
console.log(newSet)//{1, 2, 3, 4}
newSet.add(4).add(5).add(6)
console.log(newSet)//{1, 2, 3, 4, 5,6}
Set.delete(value):删除指定数据,返回一个布尔值,表示是否删除成功
let newSet = new Set([1, 2, 3]);
console.log(newSet.delete(3)); //false 表示不包含3这个元素
console.log(newSet.delete(1));//true 表示删除成功
console.log(newSet)//{1,2}
Set.has(value):判断该值是否为Set成员,返回一个布尔值
let newSet = new Set([1, 2, 3]);
console.log(newSet.has(3))//true
console.log(newSet.has(7))//false
Set.clear():清除所有数据,没有返回值
let newSet = new Set([1, 2, 3]);
newSet.clear()
console.log(newSet); // {size: 0}
size:表示Set解构的长度
let newSet = new Set([1, 2, 3]);
console.log(newSet.size)//3
5.2.3 Set去重:
let arr=[1,2,2,2,4,3,6,4];
let data=new Set(arr);
let newArr = Array.from(data);
console.log(newArr); //[1,2,3,4,6]
//或者
let arr=[1,2,2,2,4,3,6,4];
console.log([...new Set(arr)]); //[1,2,3,4,6]
六、ES6新加的数组方法及使用(Array)
6.1 新增数组方法总结
方法名 | 参数 | 返回值 | 是否影响原数组 |
---|---|---|---|
map() | 函数 | 数组 | 否 |
filter() | 函数 | 数组 | 否 |
find() | 函数 | 返回符合条件的元素,之后的值不会再调用执行函数。如果没有符合条件的元素返回 undefined | 否 |
forEach() | 函数 | undefined | 基本数据类型不改变原数组,引用数据类型改变原数组 |
includes() | 数值 | true/false | 否 |
some() | 函数 | true/false | 否 |
every() | 函数 | true/false | 否 |
6.2 新增数组方法使用
map():原数组的每一项执行函数后,返回一个新数组
let arr = [10, 20, 30, 40];
let arr1 = [];
arr.map((val) => {
val = val * 2;
arr1.push(val);
});
console.log(arr1); //[20, 40, 60, 80]
console.log("原数组", arr); //[10, 20, 30, 40]
filter():过滤数组,返回符合条件的新数组
//过滤出大于10的值
let arr = [10, 20, 30, 40]
let arr1 = [];
arr.filter((val) => {
if (val > 10) {
arr1 .push(val)
}
})
console.log(arr1 )//[20, 30, 40]
console.log("原数组", arr); //[10, 20, 30, 40]
find():查找,返回符合条件的对应的那个值
//查找id=2的值
var memoList = [{
id: 1, name: '1'
},{
id: 2, name: '2'
},{
id: 3, name: '3'
}]
// 用 editItem 变量将 查找出来的数据进行接收
var editItem = memoList.find((ele) => {
return ele.id == 2
})
console.log(editItem ) //{id: 2, name: '2'}
//但是查找id=10的值就返回underfined
var editItem = memoList.find((ele) => {
return ele.id == 10
})
console.log(editItem )//underfined
console.log("原数组", memoList ); //[{id: 1, name: '1'},{id: 2, name: '2'},{id: 3, name: '3'}]
forEach():是循环遍历数组中的每一项,没有返回值
//基本数据类型不改变原数组,引用数据类型改变原数组
let arr = [10,20,30,40];
let arr1 = [];
arr.forEach((v, i) => {
v = v * 2;
arr1.push(v);
});
console.log(arr1);//[20, 40, 60, 80]
console.log('原数组',arr);//[10, 20, 30, 40]
let arr2 = [{ v: 1 }, { v: 2 }, { v: 3 }];
let arr3 = [];
arr2.forEach((val) => {
val.v = val.v * 2;
arr3.push(val.v);
});
console.log(arr3);//[2, 4, 6]
console.log('原数组',arr2); //[{ v: 2 }, { v: 4 }, { v: 6 }]
includes():判断数组是否包含一个指定值,包含输出true,不包含输出false
let arr = [10, 20, 30, 40];
let ary = arr.includes(10);
console.log(ary);//true
console.log("原数组", arr); //[10, 20, 30, 40]
some():对数组中的每一项进行判断,若有其中一个符合条件,返回true,否则返回false
let arr = [10, 20, 30, 40];
let arr1 = arr.some(function (val) {
return val > 10;
});
console.log(arr1); //true
console.log("原数组", arr); //[10, 20, 30, 40]
every():对数组中的每一项进行判断,若都符合条件,返回true,否则返回false
let arr = [10, 20, 30, 40];
let arr1 = arr.every(function (val) {
return val > 10;
});
console.log(arr1); //false
console.log("原数组", arr); //[10, 20, 30, 40]
方法名 | 用途 |
---|---|
Array.from() | 用于将对象转换为数组,类数组转数组 |
Array.of() | 用于将一组值转化为数组 |
Array.from():用于将对象转换为数组,类数组转数组
let obj = {
0: 'zhangsan',
1: '10',
2: 'wangwu',
length:3
}
console.log(Array.from(obj))// ['zhangsan', '10', 'wangwu']
Array.of():用于将一组值转化为数组
//Array.of()使用方法:
console.log(Array.of(1,2,3))//[1,2,3]
七、ES6新加的对象方法及使用(Object)
7.1 新增对象方法总结
方法名 | 作用 | 返回值 |
---|---|---|
Object.assign() | 用于对象的合并,将原对象的所有可枚举属性,复制到目标对象 | 返回目标对象 |
Object.keys() | 获取所有对象的key属性集合 | 返回一个数组 |
Object.values() | 获取所有对象的value属性集合 | 返回一个数组 |
Object.entries() | 返回多个数组 | 返回多个数组,每个数组是 key–value |
Object.assign():用于对象的合并,将原对象的所有可枚举属性,复制到目标对象
const obj1 = { a: 1, b: 2 };
const obj2 = { b: 5, c: 3 };
//对象合并,把后面对像合并到第一个对象,对象里相同的属性会覆盖
let newobj = Object.assign({}, obj1, obj2);
console.log(newobj); // {a: 1, b: 5, c: 3}
Object.keys():获取所有对象的key属性集合
const obj1 = { a: 1, b: 2, c: 3 };
let newobj = Object.keys(obj1);
console.log(newobj); //['a', 'b', 'c']
Object.values():获取所有对象的value属性集合
const obj1 = { a: 1, b: 2, c: 3 };
let newobj = Object.values(obj1);
console.log(newobj); //[1, 2, 3]
Object.entries():返回多个数组
const obj1 = { a: 1, b: 2, c: 3 };
let newobj = Object.entries(obj1);
console.log(newobj); //[['a', 1] ['b', 2] ['c', 3]]
7.2 对象声明的简写
//ES6出现之前的写法
let a=10;
let obj={
a:a,
showa:function(){
console.log(obj.a)
}
}
//ES6出现之后的写法
let a=10;
let obj={
a,
showa:(){
console.log(obj.a)
}
}
7.3 …(对象扩展运算符)
用…表示,功能是吧数组或者类数组对象展开成一系列用逗号隔开的值,可以将类数组转真正的数组,其他功能如下:
数组合并:
let arr1=[1,2];
let arr2=[3,4];
console.log([...arr1,...arr2])//[1,2,3,4]
对象合并:
let obj1 = { a: 1 };
let obj2 = { b: 2 };
let newObj ={...obj1,...obj2}
console.log(newObj); // { a: 5, b: 2}
求数组的最大值
let arr=[1,2,3,4,5]
console.log(Math.max(...arr))//5
浅拷贝(引用传递)
let arr1 = [1, 2];
let arr2 = [...arr1];
arr2.push(3)
console.log(arr2); //[1,2,3]
console.log('原数组', arr1); //[1,2]
//或者
let obj1 = {
name: "zhangsan",
age: 10,
sex: "man",
};
let obj2 = { ...obj1 };
console.log(person2); //{name: 'zhangsan', age: 10, wife: "man"}
将类数组转真正的数组
//html:
<ul>
<li>111<li>
<li>111<li>
<ul>
//js
let aLi = document.querySelectorAll('li');
aLi = [...aLi];
aLi.push(document.body)
console.log(aLi)//[li,li,body]
八、箭头函数
1、箭头函数有更简洁的写法,不用写function
2、箭头函数是匿名函数
3、箭头函数没有prototype属性,不可以把箭头函数当作构造函数,所以不能用new关键字调用箭头函数,否则抛出一个错误、也没有arguments属性
4、箭头函数和普通函数最大的区别在于其内部this永远指向其父级的this
5、箭头函数适用于无复杂逻辑(回调函数)的函数里面,例如可以用在map()、reduce()、filter()、forEach()的回调函数中。
6、不要在最外层使用箭头函数,this会指向window,而且无法改变,最好在外层包裹一层普通函数,把this控制在可见范围内。
ler fn=function(srt)=>{
return srt
}
let fn = srt => srt;
//当只有一个参数时,括号可以省略,函数体只有单行return语句时,大括号也可以省略。
箭头函数和普通函数最大的区别在于其内部this永远指向其父级的this
var fn = () => {
alert(this);//[object Window]
};
fn()
箭头函数适用于无复杂逻辑(回调函数)的函数里面,例如可以用在map()、reduce()、filter()、forEach()的回调函数中。
let arr = [10,20,30,40];
arr.forEach((v) => {
console.log(v)
});
箭头函数没有arguments属性
function Fun(a) {//普通函数
console.log('普通函数',a)
console.log('普通函数',arguments)
}
let fun = (b) => {//箭头函数
console.log('箭头函数',b)
console.log('箭头函数',arguments)
}
Fun(12)
fun(11)
箭头函数没有prototype属性,所以不能用new关键字调用箭头函数,会报错(可以复制代码到编辑器好好研究下~)
//普通函数
function Fun(a) {
this.a=a
// console.log('普通函数', a)
}
//箭头函数
let fun = (b) => {
this.b=b
// console.log('箭头函数', b)
}
console.dir(Fun)
console.dir(fun)
let p1 = new Fun(12)
console.log('普通函数', p1)
let p2 = new fun(11)
console.log('箭头函数', p2)
九、Promise
9.1 Promise是什么
Promise是一种异步编程的解决方案,比传统的回调函数更强大更合理
let promise = new Promise((resolve, reject) => {
resolve("成功状态中的参数");
reject("失败状态中的参数");
})
//这里的then是上面的Promise实例下面的then,这里的then返回值也是一个Promise实例
.then((data) => {
console.log(data); //成功状态中的参数
})
//这里的then不是上面的Promise实例下面的then,是前一个then返回的Promise实例
.then((data) => {
console.log(data); //underfined
})
.catch((data) => {
console.log(data); //失败状态中的参数
}).finally(()=>{
console.log('无论成功或者失败,都执行'); //失败状态中的参数
}
)
9.2 Promise的特点
1、Promise有三种状态,分别是peding(进行中)、resolve(成功)、rejected(失败),并且状态一旦设定就不会改变
2、Promise是用于解决传统回调函数的回调地狱的问题
3、Promise是函数做参数
9.3 Promise下的方法
1、 then()方法:接收Promise中resolve(成功)传进来的方法和参数,then()方法也返回一个Promise对象,并且then()方法可以链式调用
2、 catch()方法:接收Promise中rejected(失败)传进来的方法和参数
3、 finally()方法:无论是成功状态还是失败状态,都执行finally()中的方法
9.4 Promise下的静态方法
1、 Promise.all():
用于将多个Promise实例,包装成一个新的Promise实例,接受一个数组做参数,只有数组里面的每个状态都变成resolve,则新的Promise实例状态才会变成resolve,输出是一个数组,Promise.all()方法常用于并发请求,比如页面多个不相关的请求接口,使用并发请求可以有效减少页面响应时间,比如批量上传图片,如果有一个图片失败则终止上传等等
再次注意::
- 当a1,a2,a3的状态都变为resolve时,a的状态才会变成resolve,此时a1,a2,a3返回值组是一个数组,传递给a中回调函数
- 当a1,a2,a3中有一个状态变为rejected时,a的状态就变成rejected,第一个状态变为rejected的返回值就会传递给a中的回调函数
const a1 = new Promise((resolve,reject)=>{
});
const a2 = new Promise((resolve,reject)=>{
});
const a3 = new Promise((resove,reject)=>{
});
const a= Promise.all([p1,p2,p3]);
Promise.all([a1,a2]).then(data=>{
console.log(data) // data为一个数组 ['请求成功','上传成功']
}).catch(err=>{
console.log(err)
})
Promise.all([a1,a2,a3]).then(data=>{
console.log(data)
}).catch(err=>{
console.log(err) // 失败 打印结果为 'error'
})
2、 Promise.race():
无实际用处,面试会问到
const a1 = new Promise((resolve,reject)=>{
});
const a2 = new Promise((resolve,reject)=>{
});
const a3 = new Promise((resove,reject)=>{
});
const a = Promise.race([a1, a2, a3]);
上面代码中,只要a1、a2、a3之中有一个实例率先改变状态,a的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给a的回调函数
十 、class(面向对象编程)
1、是ES6提供了更接近传统语言高级的写法,引入class(类)这个概念,作为对象的模板,通过class关键字,可以定义类
2、基本上ES6的class可以看作是语法糖,他的绝大部分功能,ES5都能做到,新的class写法只是让对象原型的写法更清晰,更像面向对象的编程写法而已
//class的固定写法
class Person {
constyuctor(name,age){
this.name=name;
this.age=age;
}
init(){
return this.name + this.age
}
}
十一、模块化开发
11.1 导入
ES6使用关键字 import 导入模块(文件),有两种常用的方式:
import '模块名称' from '路径';
import '路径';
11.2 导出
ES6 通过 export 和export default 导出模块。
let name = 'ren',age = 10;
export {name,age};//变量需要用大括号
11.3 模块化优点
1、灵活架构,焦点分离
2、方便模块间组合、分解
3、方便单个模块功能调试、升级
4、多人协作互不干扰
11.4 模块化缺点
性能损耗
1、系统分层,调用链会很长
2、模块间发送消息会很耗性能
总结
本文章仅限于本人自己知识点的梳理,如有不正确,欢迎指正