一、变量相关(let、var、const、function)
let、const 与 var 的区别(五个):
2.变量提升
---把当前作用域中所有带var、function关键字的进行提前的声明和定义 【预解析】
- var 会提升变量的声明到当前作用域的顶部; let、const 不存在变量提升.
3.块级作用域
4.暂时性死区
- 只要作用域内存在 let、const,它们所声明的变量或常量就自动“绑定”这个区域,不再受到外部作用域的影响,let、const 存在暂时性死区
var name='jack';
{
name='bob';
let name; //Uncaught ReferenceError: Cannot access 'name' before initialization
}
5.window 对象的属性和方法
:
二.模板字符串
- 模板字符串用反引号表示,可以在里面直接使用字符串,还可以使用变量、表达式通过
${}
注入 - 模板字符串中,所有的空格、换行或缩进都会被保留在输出之中
三.箭头函数
1.箭头函数的结构
const/let 函数名 = 参数 => 函数体
const add = () => {};
2.箭头函数简化---- 单个参数可以省略圆括号,单行函数体可省略花括号及return
3.this 指向
1.全局作用域中的 this 指向
console.log(this); // window
2.一般函数(非箭头函数)中的 this 指向
// 'use strict';
function add() {
console.log(this);
// 严格模式就指向 undefined
// undefined->window(非严格模式下)
}
add();
3.点击事件的this指向
document.onclick = function () {
console.log(this); //this指向document
};
// 只有在函数调用的时候 this 指向才确定,不调用的时候,不知道指向谁
// this 指向和函数在哪儿调用没关系,只和谁在调用有关
// 没有具体调用对象的话,this 指向 undefined,在非严格模式下,转向 window
4.箭头函数中的 this 指向
箭头函数没有自己的 this,所以会从上级上下文一层一层的往外找this,最后找到window,他的this指向window
4.不适用箭头函数的场景
- 1.箭头函数不能作为构造函数
- 2.需要 this 指向调用对象的时候,不能用箭头函数
document.onclick = function () { console.log(this); }; document.addEventListener( 'click', () => { console.log(this); //window }, false );
- 3.需要使用 arguments 的时候,不能用箭头函数,箭头函数中没有 arguments
四.解构赋值
4.1 数组解构赋值(索引值相等和模式匹配)
4.1.1 默认值,没有解构出来,就用默认值(惰性求值)
4.1.2 数组解构赋值应用
-
1.常见的类数组的解构赋值
-
2.函数参数的解构赋值
-
3.交换变量的值
4.2 对象解构赋值(模式匹配和属性名相同)
//属性名相同的完成赋值,可以取别名
const { age, username: uname } = { username: 'Alex', age: 18 };
console.log(age, uname);//解构赋值之后再赋值给uname
-
默认值和数组的一样
-
如果将一个已经声明的变量用于对象的解构赋值,整个赋值需在圆括号中进行,防止被当成块级作用域
let x = 2; ({ x } = { x: 1 }); console.log(x); //1
对象解构赋值的应用
- 1.函数参数的解构赋值
const PersonInfo = (user) => console.log(user.username, user.age);
PersonInfo(({ age, username: username } = { username: "alex", age: 18 })); //alex 18 使用了解构后的值
const person = ({ age = 0, username = "ZhangSan" }) =>console.log(username, age);
person({}); //ZhangSan 0 使用了默认值
person({ username: "alex", age: 18 }); //alex 18 使用了解构后的值
- 2.复杂的嵌套
4.3 字符串的解构赋值
- 字符串可以按照数组形式的解构赋值
- 字符串可以按照类数组对象形式的解构赋值(可以按照索引值和length)
五.对象字面量增强
5.1 属性和方法简写
在对象中属性名和值相等可以简写;方法可以直接写,也不用function声明
const age=18
const obj={
age,
fn(){}
}
5.2.方括号语法增强--属性名可以写变量啦
const name = 123;
const obj = {
["age"]: 18,
[name]: "蔡徐坤",
};
console.log(obj);//{123: "蔡徐坤", age: 18}
六、函数参数默认值-可以给形参设置默认值,不传参则使用默认值
七.剩余参数与展开运算符
剩余/扩展运算符同样也是ES6一个非常重要的语法,使用3个点(...),后面跟着一个含有iterator接口的数据结构
7.1 剩余参数--参数变数组
剩余参数可以将多余的实参组成一个数组,可以在函数形参的最后一个位置通过...args
设置,
7.1.1 箭头函数的剩余参数
7.1.2 剩余参数的应用
- 1.完成 add 函数
- 2.与解构赋值结合使用
7.2 数组展开运算符---将一个数组转为用逗号分隔的参数序列,主要用于函数调用。
console.log(Math.min(...[3, 1, 2]));
7.2.1 替代函数的 apply 方法
由于扩展运算符可以展开数组,所以不再需要apply方法,将数组转为函数的参数了,apply方法第二个参数是数组实参。
7.2.2 数组展开运算符的应用
- 1.复制数组(深拷贝)
const a = [1, 2];
const c = [...a];
a[0] = 3;
console.log(a);//[3,2]
console.log(c);//[1,2]
- 2.合并数组(浅拷贝)
const arr1 = ['a', 'b'];
const arr2 = ['c'];
const arr3 = ['d', 'e'];
// ES5 的合并数组
arr1.concat(arr2, arr3);
// [ 'a', 'b', 'c', 'd', 'e' ]
// ES6 的合并数组
[...arr1, ...arr2, ...arr3]
// [ 'a', 'b', 'c', 'd', 'e' ]
- 3.字符串转为数组
console.log([...'alex']);//['a','l','e','x']
console.log('alex'.split(''));//es6之前
- 4.常见的类数组转化为数组
4.1 arguments
function func() {
console.log([...arguments]);
}
func(1, 2);
4.2 NodeList
console.log([...document.querySelectorAll('p')]);
-
- 实现了 Iterator 接口的对象
let nodeList = document.querySelectorAll('div');
let array = [...nodeList];
7.3 对象展开运算符的基本用法
对象的扩展运算符(...)用于取出参数对象的所有可遍历属性,拷贝到当前对象之中。
1. 展开对象(深拷贝对象)
- 对象不能直接展开,必须在 {} 中展开
- 对象的展开:把属性罗列出来,用逗号分隔,放到一个 {} 中,构成新对象
const apple = {
color: "红色",
shape: "球形",
taste: "甜",
};
const Ob = { ...apple };
console.log(Ob);
console.log(Ob === apple); //false
2.合并对象,后面的同属姓名会覆盖前面的
3. 用户参数和默认参数合并,默认参数写前面,用户参数写后面
4.注意事项---如果展开的不是对象,则会自动将其转为对象,再将其属性罗列出来,类数组对象
八.Symbol唯一值
//1.需要使用Symbol()函数初始化
let name1 = Symbol('liming');
let name2 = Symbol('liming');
console.log(name1 == name2); //false
// 希望能够多次使用同一个symbol值
let name1 = Symbol.for('name'); //检测到未创建后新建
let name2 = Symbol.for('name'); //检测到已创建后返回
console.log(name1 === name2); // true
//能够访问的方法:Object.getOwnPropertySymbols.该方法会返回一个数组,成员是当前对象的所有用作属性名的Symbol值。
let id = Symbol("id");
let obj = {
[id]:'symbol'
};
let array = Object.getOwnPropertySymbols(obj);
console.log(array); //[Symbol(id)]
console.log(obj[array[0]]); //'symbol'
九.Set 和 Map 数据结构
9.1 Set数据结构---类似于数组( value = key),但没有重复的值。
Set 构造函数的参数--可以接受一个数组(或者具有 iterable 接口的其他数据结构如字符串、arguments、NodeList、Set)作为参数,用来初始化。
var s2 = new Set([1, 2, 3]);
console.log(s2, typeof s2); //Set(3) {1, 2, 3} "object"
// 1. add添加成员(可以连写)
const s = new Set();
s.add(1).add(2).add(2);
console.log(s);//{1,2}
// 2. has判断是否有某个成员
const s = new Set(["ccc", "ssss", "dddd"]);
console.log(s.has("dddd")); //true
// 3.delete删除某个成员
s.delete("dddd");
// 4. clear全部清除
s.clear();
// 5.属性size--用来获取成员个数,相当于length
// 6.遍历操作(四个方法),Set 中 value = key
// Set.prototype.keys():返回键名的遍历器
// Set.prototype.values():返回键值的遍历器
// Set.prototype.entries():返回键值对的遍历器
/*
Set.prototype.forEach():使用回调函数遍历每个成员,有两个参数,
第一个是回调函数,第二个是改变this指向
*/
const s = new Set(["蔡徐坤", "李易峰", "易烊千玺"]);
s.forEach(function (value, key, set) {
console.log(this);//document
console.log(value, key, set === s);//蔡徐坤 蔡徐坤 true
}, document);
// 按照成员添加进集合的顺序遍历
Set 应用
1.数组去重
console.log([...new Set([1, 2, 1])]);
const s = new Set('abbacbd');
console.log(s);//{'a','b','c','d'}
console.log([...s].join(''));
console.log(s);
//一行搞定
console.log([...new Set('abbacbd')].join(''));
<p>1111</p>
<p>22222</p>
<p>3333</p>
// for()
const s = new Set(document.querySelectorAll('p'));
console.log(s);
s.forEach(function (elem) {
console.log(elem);
elem.style.color = 'red';
elem.style.backgroundColor = 'yellow';
});
十.Iterator 和 for...of 循环
10.1 Iterator遍历器(迭代器)
10.2 为什么需要 Iterator 遍历器--for..of 来遍历
我们之前的遍历方法是:
- 遍历数组:for 循环和 forEach 方法
- 遍历对象:for in 循环
而 Iterator 遍历器是一个统一的遍历方式,使用 Iterator 封装好的 for..of 来遍历,不管是数组还是对象都可以遍历
10.3 原生可遍历(有Iterator接口)
- 一般的对象可以用for ... in遍历,也可以给他添加一个Symbol.iterator然后用for ... of 遍历
10.2.1 for...of 遍历数组
const arr = [1, 2, 3];
//1.遍历出索引值arr.keys() 得到的是索引的可遍历对象
for (const key of arr.keys()) {
console.log(key);
}
//2.遍历出值arr.values() 可以等价于arr
//3遍历出[index,value]用arr.entries() 得到的是索引+值组成的数组的可遍历对象
10.2.2 for...of 遍历普通对象Object.entries(obj)
十一.Es6新增方法
11.1 Es6字符串新增方法(3个)
1. includes()判断字符串中是否含有某些字符
//判断字符串
console.log('abc'.includes('a', 0));//true
1.第一个参数------表示是否包含该值
2.第二个参数----- 表示开始搜索的位置,默认是 0,index
//判断数组
arr = ["name", 2, 3, 4, 5, 6, 7, 8];
console.log(arr.includes("name"));//true
应用:给url添加参数,判断url有没有问号,有问号说明有key=value
,再添加就直接添加连接符&key=value
2.padStart() 和 padEnd()在字符串本身的头部或尾部补全字符串长度
console.log("abc".padStart(10, "0123456789")); //0123456abc
console.log("abc".padEnd(10, "0123456789")); //abc0123456
// 第一个参数表示补全后的字符串长度(有几个),第二个参数是要用到的元素补全字符串
// 如果省略第二个参数,默认使用空格补全长度
应用----显示日期格式
3.trimStart() 和 trimEnd()清除字符串的首或尾空格
const s = ' a b c ';
console.log(s);
console.log(s.trimStart());
console.log(s.trimEnd());
应用-表单验证提交
11.2 Es6数组新增方法(三个)
1.includes()
- 判断数组中是否含有某个成员
- 第二个参数表示搜索的起始位置,默认值是 0
应用-数组去重
const arr = [];
for (const item of [1, 2, 1]) {
if (!arr.includes(item)) {
arr.push(item);
}
}
console.log(arr); //[1,2]
2.Array.from()将类数组对象或可迭代对象转化为数组
-
一个类数组对象必须含有 length 属性,且元素属性名必须是数值或者可转换为数值的字符。
-
可迭代对象(数组、字符串、Set、Map、NodeList、arguments)。
-
元素属性名不为数值且无法转换为数值,返回长度为 length 元素值为 undefined 的数组
-
第一个参数---能被转化的数据对象。
-
第二个参数---作用类似于数组的 map 方法,用来对每个元素进行处理,将处理后的值放入返回的数组
-
第三个参数--第二个参数为一般回调函数时,第三个参数可以改变 this 指向
let a = {
0: "aaa",
1: "bbb",
2: "cccc",
3: "ddd",
4: "eeee",
length: 5
};
let array1 = Array.from(a, (value) => value + "你真帅");
console.log(array1); // ["aaa你真帅", "bbb你真帅", "cccc你真帅", "ddd你真帅", "eeee你真帅"]
3.find(callback)返回元素 和 findIndex()返回索引
findIndex()用法结构类似,但是,返回数组中第一个满足条件的索引(从0开始), 不满足返回-1;
应用-筛选数据
const students = [
{
name: "张三",
sex: "男",
age: 16,
},
{
name: "李四",
sex: "女",
age: 22,
},
{
name: "王二麻子",
sex: "男",
age: 32,
},
];
console.log(students.find((value) => value.sex === "男"));
console.log(students.findIndex((value) => value.sex === "女"));
11.3 Es6对象新增方法(2个)
1.Object.assign()合并对象
- Object.assign(目标对象, 源对象 1,源对象 2,...): 目标对象
- Object.assign 直接合并到了第一个参数中,返回的就是合并后的对象
应用--合并默认参数和用户参数
const logUser = (userOptions) => {
const DEFAULTS = {
username: "ZhangSan",
age: 0,
sex: "male",
};
const options = Object.assign({}, DEFAULTS, userOptions);
console.log(options);
};
logUser();
2.Object.keys()、Object.values() 和 Object.entries()
- 数组的 keys()、values()、entries() 等方法是实例方法,返回的都是 Iterator
- 对象的 Object.keys()、Object.values()、Object.entries() 等方法是构造函数方法,返回的是数组
const person = {
name: "Alex",
age: 18,
};
console.log(Object.keys(person)); //['name',"age"]
console.log(Object.values(person));//["Alex", 18]
console.log(Object.entries(person)); //二维数组 [["name", "Alex"],["age", 18]]
应用-和for...of...一起遍历对象
obj = { name: "蔡徐坤", age: "18", hobby: ["唱歌", "写歌", "跳舞"] };
console.log(Object.entries(obj));
for (key of Object.entries(obj)) {
console.log(key[0], key[1]);
}
十二.Promise对象
- Promise是ES6中新增的异步编程解决方案, 他是一个构造函数,在代码中通过
new Promise()
生成一个实例对象。精髓是通过状态调用用对应的回调函数。 Promise对象可以将异步操作以同步流程来表示, 避免了回调函数层层嵌套(回调地狱)。
12.1 基本使用
//Promise是一个构造函数
let p = new Promise(executor)
let p=new Promise((resolve,reject)={
/*
执行器函数里面,一般存放的都是我们即将要处理的异步任务(比如网络请求),任务成功我们执行resolve吧数据传出去, 任务失败我们执行reject(当然写同步的也可以),之后根据状态就可以调用原型里面的三个方法
*/
})
12.2 Promise.prototype.then()方法的使用(可以多次使用)
-
then 方法接收两个
函数为参数
,第一个参数是 Promise 执行成功时的回调,第二个参数是 Promise 执行失败时的回调,两个函数只会有一个被调用。 -
then()方法执行后返回的是一个新的 Promise 对象,这个promise的状态由then里面执行的回调函数的返回值决定,返回值是非promise对象,他的状态就是成功的,返回值是promise对象,状态就由这个对象决定
// Promise对象的结构;
{
[[PromiseState]]: "fulfilled"
//第一个由resolve或reject决定,后面执行的then返回的对象状态由当前函数返回值决定
[[PromiseResult]]: "222"
//结果就是当前Promise对象调用then之后return的值,
}
12.2 Promise.prototype.catch()方法的使用
- .catch()专门监听失败的回调
- 如果需要分开监听,用
.then().catch()
方法使用链式编程,promise的状态如果是失败, 但是没有对应失败的监听就会报错 - 和then方法第二个参数的区别在于, catch方法可以捕获上一个promise对象then方法(也包括成功的回调的方法)中的异常。
js异常处理
try {
可能遇到的意外的代码
}
catch(e) {
捕获错误的代码块
}
12.3 Promise.all()方法的使用
- 应用场景: 批量加载, 要么一起成功, 要么一起失败
12.4 Promise.race()方法的使用
- 应用场景: 接口调试, 超时处理
给超时函数和加载函数均包装一个promise对象,然后把这个对象写入race里面,紧接着写处理函数,5s之内没有获取资源,就直接超时处理
12.5 Promise.resolve()和Promise.reject()方法的使用
Promise.resolve()返回一个成功的Promise对象
p = Promise.resolve("success");
console.log(p);
/*
[[PromiseState]]: "fulfilled"
[[PromiseResult]]: "success"
*/
Promise.reject()返回一个失败的Promise对象
p = Promise.reject("failed");
p.catch((err) => console.log(err));
console.log(p);
/*
[[PromiseState]]: "rejected"
[[PromiseResult]]: "failed"
*/
Promise封装网络请求放到网络
那一块
- 买菜(20分钟)-->做饭(30分钟)-->送饭(十分钟)-->通知;都是耗时的异步任务
- 搞很多函数(买菜函数、做饭函数、送饭函数、亲一个函数),均接受resolve函数参数,并在定时器里面执行resolve把做好了的事情发过去。
new Promise(买菜).then((买好的菜)=>{
return new Promise(做饭);
}).then((做好的饭)=>{
return new Promise(送饭);
}).then((送饭结果)=>{
老婆亲一个();
}).catch(err=>throw new Error(err))
//写好任务计划表
function 买菜(resolve,reject) {
setTimeout(function(){
resolve(['西红柿'、'鸡蛋'、'油菜']);
},3000)
}
function 做饭(resolve, reject){
setTimeout(function(){
//对做好的饭进行下一步处理。
resolve ({
主食: '米饭',
菜: ['西红柿炒鸡蛋'、'清炒油菜']
})
},3000)
}
function 送饭(resolve,reject){
//对送饭的结果进行下一步处理
resolve('老婆的么么哒');
}
function 电话通知我(){
//电话通知我后的下一步处理
给保姆加100块钱奖金;
}
//开始做任务
// 告诉保姆帮我做几件连贯的事情,先去超市买菜
new Promise(买菜)
//用买好的菜做饭
.then((买好的菜)=>{
return new Promise(做饭);
})
//把做好的饭送到老婆公司
.then((做好的饭)=>{
return new Promise(送饭);
})
//送完饭后打电话通知我
.then((送饭结果)=>{
电话通知我();
})
十三.async 函数
- 1.给函数加上一个async修饰符之后,函数执行的结果是一个成功的promise对象,我们可以直接在函数执行语句后面用then。
async function foo() {
//1.返回成功的
//return Promise.resolve();
return 1;
// 2.返回失败的
// return Promise.reject();
// throw new Error("我错了");
}
foo().then((res) => {
console.log(res); //1
});
- 2.await只能在async函数里面执行,否则会报错,它的含义是等待一个promise实例成功后执行。
面试题:编写一个 sleep 函数,让其等待 1000ms 后再去做其他事情?
- 方案一:用定时器
- 方案二:函数返回值为Promise对象
function sleep(interval = 5000) {
return new Promise((resolve) => {
setTimeout(resolve, interval);
});
}
sleep(2000).then(() => {
console.log("我在2000ms之后执行");
});
- 方案三:利用await语句
function sleep(interval = 1000) {
return new Promise((resolve) => {
setTimeout(resolve, interval);
});
}
(async function () {
//买菜需要八秒
await sleep(8000);
//菜卖回来了通知我
console.log("我在1000ms之后执行");
//做饭需要两秒
await sleep(2000);
//饭做好了通知我
console.log("我在2000ms之后执行");
//吃饭需要5s
await sleep(5000);
//吃完饭了通知我
console.log("我在5000ms之后执行");
})();
十四.Module 的语法
变量或函数加载
- 若果要输出变量或函数,直接在其最前面加上export,而使用其他模块中变量时,则使用import引入
//1.export 设置对外接口
export var name='蔡徐坤'
export function multiply() {}
export { firstName, lastName, year }
//import 命令加载这个模块(对外对内接口名相同)。
//import 命令输入的变量都是只读的,不允许在加载模块的脚本里面,改写接口。
//import 命令具有提升效果,会提升到整个模块的头部,首先执行。
import { firstName, lastName, year } from './profile.js'
模块的整体加载---export default
命令
// export-default.js
export default function () {
console.log('foo')
}
// import-default.js
import customName from './export-default'
customName() // 'foo'
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!