声明变量
let:
1: 不能重复申明变量
2:是一个块级作用域,只在代码块中起效
3:不存在变量提升,不能在申明之前定义变量
let使用的实例,比var更加的方便快捷,然后可读性更强。
let div = document.querySelectorAll('div');
for (let i = 0; i < div.length; i++) {
div[i].addEventListener('click', function () {
// 排他思想
for (let j = 0; j < div.length; j++) {
// 在这个里面不用this 也可以,因为let只对块级代码起作用,所以每个 i的值只在每一个循环中起作用。
div[j].style.backgroundColor = '';
}
div[i].style.backgroundColor = 'pink';
})
}
const
1,一定要给他赋一个初始值
2,推荐变量使用小写
3,常量的值不能修改
4,作用于块级作用域
5,对于数组和对象发生改变是不会报错的
变量的解析赋值
数组用[]
对象用{}
数组的解析解构赋值
const f4 = ['赵本山', '宋小宝', '李丹丹', '小沈阳'];
let [zhao, song, li, sheng] = f4;
console.log(zhao);
console.log(song);
console.log(li);
console.log(sheng);
给对象赋值,注意花括号里面定义的名字必须要和类的属性名一致
const zhao = {
name: 'zcy',
age: 18,
}
let {name, age} = zhao
console.log(age);
console.log(name);
反引号的使用
以前的单引号输入字符串的时候,在字符串中不能换行,反引号可以换行
使用反引号,凭借字符串不用+号,直接就用${}
let love=你好;
let str=${love}zcy;
console.log(str);
对象简化
可以将对象的里面的function省去
可以不重复命名
箭头函数
箭头函数没有自己的this,他的this是指向近一层的作用域
简单来说,箭头函数没有自己的作用域链,她只有往上去找
function函数可以将对象实例化,但是箭头函数不行,箭头和函数你可以将它理解为一个表达式
这里举一个列子,箭头函数作用域的列子
let fn=(a,b)=>{
console.log(this);//输出window ,因为箭头函数没有作用域链,所以只能往上查找,就只有window
}
fn();
let a =n=>{
return n\*n;
}
console.log(a(5));
// 当代码体只有一台语句的时候
let b=n=>n\*n
console.log(b(4));
箭头函数中的this是指向申明所在的作用域下的this值
箭头函数的实例
// 箭头函数筛选数组中的偶数
let arr = [1, 3, 5, 63, 8, 10];
// filter方法表示筛选,返回true则表示保留,false就去掉
let result = arr.filter(items =>{
if(items % 2 === 0){
return true;
}else{
return false;
}
})
console.log(result);
可简化
// 箭头函数筛选数组中的偶数
let arr = [1, 3, 5, 63, 8, 10];
// filter方法表示筛选,返回true则表示保留,false就去掉
let result = arr.filter(items => items % 2 === 0)
console.log(result);
解构赋值
// es5
let dates = {
name: 'zcy',
age: 19
}
let name = dates.name;
let age = dates.age;
console.log(name, age);
// es6
let date = {
name: 'zcy',
age: 19
}
let {name,age}=date;
console.log(name,age);
箭头函数与解析赋值结合
// 与解构赋值结合
function connect({name, age, school,love="xiaxia"}){
在这里如果参数没有这个值,可以手动赋值
console.log(name);
console.log(love);
}
connect({
name: zheng,
age: 19,
school: swpu,
})
对像的扩展
//更方便赋值,取值
let name='zcy';
let age =19;
let date={
name,//name=name;
age,//age=age
sayhi:function(){
console.log('你好');
}
}
date.sayhi();
Object.is()等价于===
Object.assign()的作用在于将后面的对象合并给第一个对象
let o=Object.assign({},{name:'zcy',age:19},{name:'xyr',age:18})
console.log(o);//这里返回的只有xyr 18 因为他们的属性名相同 后面的会将前面的覆盖掉
let newobject=Object.assign({},{a:1},{b:1})
console.log(newobject);//这里返回的就是a:1 ,b:1
console.log(Object.is(NaN,NaN));//返回true
//is()是执行完全相等,只要有相同就返回true,但是其实NaN是不相等的
rest参数
// rest参数 他的意义在于 你给函数赋值的的时候可以改变复赋值的个数
function date(...args){
console.log(args);
}
date(1,2,3,3,32,45);
// 注意使用rest参数的时候要将rest参数放到最后
function date(a,b,...args){
console.log(args);
}
date(1,2,3,4,5)
//args输出[3, 4, 5]
扩展运算符
// 扩展运算符
// ...谁谁谁就带表了这个元素里面的所有元素
const date = [1, 2, 3, 4, 54, 6];
const date1 = [...date];
console.log(date1);
sybmol的运用
sybmol可以有效解决命名重复的问题
sybmol不能与其他数据进行一个运算
syboml定义的属性在对象里面要用中括号表示
他的基本用法
let s1=Symbol('s1');//我给这个symbol加一个注释's1'
let dates={
[s1]:'小马哥'
}
console.log(dates.s1);//这样是获取不到的
// 如果想要获取对象中的symbol属性
let s=Object.getOwnPropertySymbols(dates);
console.log(s);
symbol给对象安全添加属性
// 对一个对象扩展属性,因为我不知道这个对象里面有没有up和down所以我用sybmol以免重复
// 方法一
let game = {
game: 俄罗斯方块
};
let medthod = {
up: Symbol(),
down: Symbol()
}
game[medthod.up] =function(){
console.log('我正在快速上升');
}
game[medthod.down]=function(){
console.log('我正在快速下降');
}
console.log(game);
// 方法二
let game = {
game: '俄罗斯方块',
[Symbol('say')]: function () {
console.log('我可以说话')
},
[Symbol('zibao')]: function () {
console.log('我可以自爆');
}
}
console.log(game);
isConcatSpreadable(阻止/允许展开)
let arr1=[1,2,3,4]; let arr2=[1,23,4,55,66,77]; //这里是让arr2不展开,就以arr2的形式存在新数组中 arr2[Symbol.isConcatSpreadable]=false; //concat是用来连接两个字符串的 console.log(arr1.concat(arr2));
set集合的方法
// set 和has方法
let set=new Set();//先定义一个集合,set集合(存储的元素是有序不重复的)
set.add(1);//添加一个1到集合
set.add('4');
set.add('4');//set集合里面不能有重复,只会显示一个4
set.add([1,2,3])
set.delete('4')//删除
console.log(set);
console.log(set.has(1));//判断是否存在1 返回true
// 集合转数组
let set=new Set([1,2,3,4,5]);
let arr2=[...set];
console.log(arr2);
map集合的方法
1,map函数是以键值对的形式存在的,是一个有序列表
具有set设置,get获取,clear清除,delete删除,has判断方法
// Map集合
let map = new Map();
map.set('name', 'zcy');
console.log(map.get('name'));//在这里你设置的值是‘name’带有引号
map.set('age',19)
console.log(map.get('age'));//Map集合在获取值的时候应该带上引号,设置值的时候也要在字符串带上引号
console.log(map.has('name'));//has()方法用来判断是否含有此字符串
// 同样Map也有clear delete方法
数组新增的方法 Array.from()of(),find(),findindex()
// form方法 将伪数组转化为真正地数组
function sum(){
let arr=Array.from(arguments);
console.log(arguments);
}
sum(1,2,3)
// Array.of()可以将任意的数字转化为数组
let arr = Array.of(1, 32, 3, 4, 3, [1, 23, 34, 5], [id = 'zcy']);
//在of里面可以加数组,id等都可以
console.log(arr);
find方法就是找出数组中第一个符合条件的数,findindex就是找出第一个符合条件的数的索引号
let arr = [1, 23, 4, 5, 6, 10, 18];
let arr1 = arr.find((n) =>{
return n>10
})
console.log(arr1);
// 简写
let arr2 = [1, 2, 3, 66, 77].find((n) => n > 10)
console.log(arr1);
数组新增方法二 (遍历)
console.log([‘a’, ‘b’].keys());//keys()是对键进行遍历,返回的是一个遍历器 Array Iterator {},你可以理解为获取一个键的遍历器,那样才能对数组遍历
// 我们有了遍历器就可以进行for... of...的遍历
for (let key of ['a', 'b'].keys()) {
console.log(key);
// 输出0,1
}
// value是对数组的值进行遍历
for(let index of ['a','b'].values()){
console.log(index);
}
// for in 也可以直接获取值,for of获取键
let arr=['a','b'];
for(let index in arr){
console.log(index);
}
迭代器
迭代器是一个接口,快捷访问数据
const arr = [1, 2, 3, 4];
let items = arrSymbol.iterator;//这里的意思是在arr数组上面加装一个迭代器,使他可以进行迭代
console.log(items.next());
console.log(items.next());
console.log(items.next());
[Symbol.iterator]用实现的
迭代器源码
const school = {
name: 'swpu',
stu: ['zcy', 'jhq', 'gx', 'yx', 'tjj', 'xhx'],
Symbol.iterator {
let index = 0;
let \_this = this;
return {
next: function () {
if (index < \_this.stu.length) {
const result = { value: \_this.stu[index], done: false };
return result;
index++;
} else {
return { value: undefined, done: true }
}
}
};
}
}
for (let a of school) {
console.log(a);
}
这个是更直观的感受
let date =[1,2,3];
//给date加一个迭代器
let items=dateSymbol.iterator;
console.log(items);
console.log(items.next());
console.log(items.next());
console.log(items.next());
console.log(items.next());
let date =[1,2,3];
let items=dateSymbol.iterator;
for(let a of items){
console.log(a);
}
//输出属性值
迭代器对象一般用for of 遍历
生成器
生成器是ES6中新增的一种函数控制、使用的方案,它可以让我们更加灵活的控制函数什么时候继续执行、暂停执行等。与yield一起使用
yield
在函数中执行完yield后会暂停,yield相当于函数代码的分隔符
如果不存在yield那么就会一口气执行完毕,有了yield只会执行yield前面的代码
要想执行后面必须要用next迭代器进行下一段代码执行
要用next()迭代器才能启动yield
yield返回的是value, done
生成器的使用场景:
1,给不具备迭代器对象的的对象提供遍历操作
function\* test() {
console.log("进入")
yield "遇到了第一个 yield"
console.log("我被暂停啦。。")
yield "遇到了第二个 yield"
console.log("我又被暂停啦。。")
}
let a = test()
console.log(a.next())
console.log(a.next())
// next()方法调用时可以传入实参,实参就是yeild语句返回的结果。第二个next()方法传入的实参将作为第一个yeild的返回结果。
function \* gen(arg){
console.log(arg); //aaa
let one = yield 111;
console.log(one); //BBB
let two = yield 222;
console.log(two); //CCC
let three = yield 333;
console.log(three); //DDD
}
let iterator = gen('aaa');
console.log(iterator.next('AAA'));
// 第一个next()里面的参数不被接收,但是没有第一个next()方法,那么接收第一个yeild后面自变量的参数就会后移一位,这样就不能输出所有的参数值。
console.log(iterator.next('BBB'));
console.log(iterator.next('CCC'));
console.log(iterator.next('DDD'));
回调地狱
这个指的是在异步编程的时候,定时器函数会一直往后排,不方便观看,也不方便维护
函数默认值
// es5
function comt(a,b) {
a = a || 10//a如果有默认值就取a如果没有就取10
b = b || 10
return a \* b;
}
console.log(comt());
// es6
function comt(a=10,b=10){
return a\*b;
}
console.log(comt());
arguements就是储存了传过来的实参,但是在es6中不再使用arguements,用...arr代替(arr可以自己命名);
// es6扩展运算符(比较最大值)
let arr=[1,2,3,4,5,5,6];
console.log(Math.max(...arr));
promise
promise是一个对象,在使用时必须要new一个promise对象。
规定在特定的时候调用resolve方法和reject方法 resolve(‘1212’)就是调用resolve方法
我们在使用promise的时候一般会用函数将其包裹,使用的时候才调用。
promise包括resolved(成功),rejected(失败);一般都用这个命名,相当于潜规则。
resolved的数据会传给then方法的回调函数,执行下一步操作
promise的all,catch方法
我们用then方法专门处理成功态,用 catch专门处理失败态
catch是then的实例化,catch的参数是由reject传过来的
// promise的all和catch
// 在等待图片资源的时候应用比较多
let pro1=new Promise((resolve,reject)=>{});
let pro2=new Promise((resolve,reject)=>{});
let pro3=new Promise((resolve,reject)=>{});
let pro4=Promise.all([pro1,pro2,pro3]);//all是将选中的promise对象集中在一起,传给p4
// 等我所有的异步函数都执行完的时候才执行以下代码
p4.then((n)=>{
//如果全部都正确就执行这个
}).catch((n)=>{
//只有要有一个错误就执行这个
})
promise的race方法
// promise的race方法
// race方法就是让两个函数进行比赛,和all方法类似,但是他有一个函数完成就算完成,他只会输出最先结束的那个
let pro1 = new Promise(resolve => {
setTimeout(() => {
resolve('我是p1')
})
})
let pro2 = new Promise(resolve => {
setTimeout(() => {
resolve('我是p2')
}, 1500)
});
Promise.race([pro1, pro2])//pro1先输出所以pro1竞争胜利,在pro1的基础上调用then方法
.then((value) => {
console.log(value);
})
async异步操作
其实async函数就是generator的语法糖
await后面的对象可以扩展为thenable对象(即定义了then方法的对象)
async一般和await一起使用
如果async函数有多个await,那么then要等所有的awai指令执行完成后才执行
async function foo() {
const result = await new Promise(
(resolve) => setTimeout(() => resolve(1))
)
console.log(result)
}
foo()
async function foo() {//async自己带了then方法
//在asnyc方法中不用使用 promise的判断
const result = await 1//如果await后面不是promise对象,那么await后面的值就相当于是resolve的值
await 2
await 3
console.log(result)
}
foo();
console.log(2);
//输出结果 2 1
为什么我们要使用try和catch
因为我们的await无法得到一个错误状态的promise对象,就需要通过try-catch才可以得到这个错误值
当我们在async函数中的return和throw
return任何值会默认异步成功,参数由then来接收
throw会默认异步失败,也会修改为失败状态
async function test1() {
// 返回任何值会默认异步成功,也会修改为成功状态
return 1;
};
async function test2() {
// 抛出任何值会默认异步失败,也会修改为失败状态
throw 2;
};
test1();
test2();
class类
这里的class类和java差不多
// class类
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
sayname() {
return this.name;
}
}
let p = new Person('zcy', 19);
console.log(p.sayname());
console.log(p);
// extends的用法
class Dog extends Person {
constructor(name, age, color) {
super(name, age);//这里的值不和上面的父类的一样,不是继承父类的值,而是继承父类的方法;
this.color = color;
}
saycolor() {
return this.color;//this.color的意思是我输入的color
}
}
let mydog = new Dog('bb', 1, 'red');
console.log(mydog.sayname());
console.log(mydog.saycolor());
es6的模块化
es6的模块化功能主要有两个命令构成:import和exprot
export用于规定模块的对外接口,import用于输入其他模块提供的接口
一个模块是一个独立的文件
//接收的文件
import \* as f from 'export.js';
let dog=new Dog('小红',19,'黄色');
console.log(dog.sayname());
//导入的文件