let const

let 定义变量,局部作用域,没有变量提升,只能先定义后使用,不能重复定义

const 定义常量,不能修改,如果定义的是一个对象,让这个对象不能修改,需要使用

Object.freeze(obj);

var 定义的全局变量是属于window的,let const 不同

解构赋值:

两边的结构格式必须一致:

demo1:
 
 
let [a,b,c]=[1,2,3];



console.log(a,b,c);//"1" "2" "3"
部分赋值
let [a1,,c1]=[1,2,3]; 
  
console.log(a1,c1);//"1"  "3"



demo2:



let{name,age,job}={
    name:'zhangsan',age:'12',job:'web'
};



console.log(name,age,job);//"zhangsan" "12" "web"




解构赋值可以重命名:



let{name1:n,age1:g,job1:j}={
    name1:'zhangsan',age1:'12',job1:'web'
};
console.log(n,g,j);//"zhangsan" "12" "web"



可以设置默认值



let [d,e,f=100]=[1,2];
console.log(d,e,f);//1 2 100



交换两个值:



let a=10; 
let b=5;
[a,b]=[b,a];
console.log(a,b);//5,10



对象再次赋值:需要用()包裹,否则会解析为局部作用域



let c='age';
({c}={c:'name'});
console.log(c);//name



字符串模板



let name='zhangsan'; 
let age=15;
console.log(`姓名:${name},年龄:${age}`);//姓名:zhangsan,年龄:15



1  可以随意换行 2 取值 ${}

字符串的方法:

判断是否包含某个字符串
includes() 返回true false
indexOf() 返回索引位置
字符串以谁开始:
startsWith()返回true false
字符串以谁结束:
endsWidth()返回true false
字符号重复:
repeat(次数)//重复的次数
字符号填充:
padStart(字符号长度,填充的字符串)
padEnd(字符号长度,填充的字符串)

函数默认参数 箭头函数 剩余参数



function demo({name='zhangsan',age='18'}={}){
console.log(`姓名:${name},年龄:${age}`);
}
demo();//
demo({name:'lisi'});//姓名:lisi,年龄:18
demo({age:100})//姓名:zhangsan,年龄:18
demo({name:'lisi',age:200});//姓名:lisi,年龄:200



函数的参数默认是定义过的,不能再函数体重重复定义变量

function demo(a){
let a=100;
}
报错,变量重复定义
箭头函数,
1 this问题,定义函数所在的对象,不再是运行时所在的对象(如果不会箭头函数,this执行运行时所在的对象)
2 箭头函数内没有arguments,使用...
3 箭头函数不能用于构造函数
demo
 
 
function demo3(){
    let obj= {
        id:2,
        show:function(){
           setTimeout(function(){ alert(this.id);},1000);
        }
    };
    return obj;
}
demo3().show()//undefined setTimeout是window执行的,所以this指向winidow


function demo3(){
    let obj= {
        id:2,
        show:function(){
           setTimeout(()=>{ alert(this.id);},1000);
        }
    };
    return obj;
}
demo3().show()//2  箭头函数,this指向定义时的对象,就是obj 
 
 
... 扩展运算符 Rest运算符
数组
arr.forEach(function(val,idnex,arr){}) 参数是个回调函数,替换普通的for循环
arr.map() 做数据交互映射,重新整理数据解构,正常情况下需要配合return使用,如果没有就和forEach()一样
  注意:平时用到map,就需要用到return 返回一个新的数组
arr.filter()
  过滤一些不合格的元素,如果回调函数返回的是true就留下,false就过滤掉
arr.some()
  遍历数组,类似查找,有一个符合要求就返回true
arr.every()
  遍历数组,所有元素符合要求就返回true,否则返回false
 
以上的方法接收的参数都是一样的,可以接收两个参数,循环回调函数,this指向谁;
也可以使用bind修改this的指向 arr.forEach().bind(123)
 
arr.reduce(function(prev,cur,index,arr){})  从左到右
    求数组的和prev:上次循环的结果,cur当前的值,index当前值得索引,arr数组本身
 
demo:
[1,2,3,4,5].reduce((prev,cur,index,arr)=>{return pre+cur})//15
arr.reduceRight()  从右到左
 
 
for...of....
可以用来循环数组和对象   arr.keys() arr.entries()
 Array.from:
  把类数组转换成数组,类数组需要有length属性
  如果是数组,直接复制数组

demo:



let arr=[1,2,3,4,5];
console.log(Array.from(arr));//[1,2,3,4,5]

let json={
  0:'zahngsan',
  1:'lisi',
  2:'wangwu'
}; 
console.log(Array.from(json//[]

let json={
  0:'zahngsan',
  1:'lisi',
  2:'wangwu',
  length:3
}; 
console.log(Array.from(json//['zhangsan','lisi','wangwu']

let json={
  0:'zahngsan',
  1:'lisi',
  2:'wangwu',
  length:2
}; 
console.log(Array.from(json//['zhangsan','lisi']



Array.of()   :把一组值转为数组
demo:
console.log(Array.of('1','2','3'));//[1,2,3]
arr.find()     找到第一个符合条件的数组成员,如果没有返回undefined
demo:



let arr=[1,2,3,4,5];
    let bb=arr.find((item,index,arr)=>{
        return item>3;
    });
    console.log(bb);//4



function demo(){
    let arr=[1,2,3,4,5];
    let bb=arr.find((item,index,arr)=>{
        return item>5;
    });
    console.log(bb);//undefined
}



arr.findIndex()  : 找到第一个符合条件的数组成员的索引,如果没有返回-1



function demo1(){
    let arr=[1,2,3,4,5];
    let bb=arr.findIndex((item,index,arr)=>{
        return item>5;
    });
    console.log(bb);//-1
}


function demo2(){
    let arr=[1,2,3,4,5];
    let bb=arr.findIndex((item,index,arr)=>{
        return item>3;
    });
    console.log(bb);//3
}



arr.fill(填充的内容,开始位置,结束位置) 填充数组规定位置的数据



function demo(){
    let arr=[1,2,3,4,5];
    let bb=arr.fill('x',0,2);
    console.log(bb);//['x','x',3,4,5]
}



arr.includes()

对象

对象的简洁语法



let name='zhangsan';
let age=20;
let json={
  name,//name:name
  age//age:age
}



Object.is(值1,值2);比较两个值是否相等
console.log(NaN==NaN);//false
Object.is(NaN,NaN);//true
console.log(N0==-0);//true
Object.is(0,-0);//false
Object.assign(目标对象,source1,source2,...source3) ///合并对象,后面的值覆盖前面的值

作用: 就复制一维对象     合并参数



Object.assign([],[2,3,4,5])//[2,3,4,5]
Object.assign({},{name:'zhangsan'})//{name:'zhangsan'}



Object.keys()   Object.values()  Object.entries()

demo:



let {keys,values,entries}=Object;//解构赋值
let json={name:'zhangsan',age:20};
for(let key in keys(json))console.log(key)//name  age
等价于:
for(let key in Object.keys(json))console.log(key)//name  age

for(let value in values(json))console.log(value)//'zhangsan' 20
等价于:
for(let value in Object.values(json))console.log(value)//'zhangsan' 20



对象的解构赋值...

Promise

作用: 解决异步回调问题



let a=10;
   var promise=new Promise(function(resolve,reject){
       if(a==100){
        resolve('成功');
       }else{
        reject('失败');
   }
   });
      promise.then(res=>{
           console.log(res);
      }).catch(err=>{
        console.log(err);
      });



Promise.resolve('aa')//将现有的东西转成一个promise对象,reslove状态,成功状态

Promise.reject('bb')//将现有的东西转成一个promise对象,reject状态,失败状态



let a=Promise.resolve('aaa');
   等价于: a=new Promise((resolve,reject)=>{
            resolve('aaa');
   });
   a.then(res=>{
       console.log(res);
   })
   

   let b=Promise.reject('bbb');
   等价于: b=new Promise((resolve,reject)=>{
    reject('bbb');
});
   b.catch(res=>{
       console.log(res);
   })



Promise.all([p1,p2,p3,...])//把promise打包,扔到一个数组里面,打包完之后还是一个Promise对象,必须确保,所有的promise对象,都是resolve状态,都是成功的状态,其中有一个不是就会报错,走的是reject

demo:



let a=Promise.resolve('aaa');
   let b=Promise.resolve('bbb');
   let c=Promise.resolve('ccc');
   Promise.all([a,b,c]).then(res=>{
    console.log(res);//['aaa','bbb','ccc']
   }).catch(err=>{
    console.log(err);
   });


let a1=Promise.resolve('aaa');
let b1=Promise.resolve('bbb');
let c1=Promise.resolve('ccc');
   Promise.all([a1,b1,c1]).then(res=>{
    console.log(res);
   }).catch(err=>{
    console.log(err);//bbb
   });



Promise.race([p1,p2,p3,...])//跟Promise.all()的区别:一旦迭代器中的某个promise解决或拒绝,返回的 promise就会解决或拒绝。
模块化:
commonjs  主要服务端: nodeJS
AMD     requireJs curJs
CMD    seaJs
1 如何定义模块
2 如何使用模块
使用模块:
<script type='module'></script>
导出模块: export
导入模块:import   路径可以是相对路径也可以是绝对路径,无论导入多少次,只会被导入一次
import  '文件路径'//相当于导入一个文件
demo:



1.js
const a=1;
const b=2;
const c=3;
export{a,b,c}
2.js使用
import {a,b,c} from '1.js'
console.log(a,b,c);// 1 2 3
//名字要一致

变量名可以重命名
1.js
const a=1;
const b=2;
const c=3;
export{a as aaa,b as bbb,c as ccc}
2.js使用
import {aaa as a ,bbb as b,ccc as c} from '1.js'
console.log(a,b,c);// 1 2 3
3.js使用
import {aaa ,bbb,ccc} from '1.js'
console.log(aaa,bbb,ccc);// 1 2 3



导入所有导出的数据

import * as demo from '1.js



1.js
const a=1;
const b=2;
const c=3;
export{a,b,c}
2.js
import * as demo from '1.js'
console.log(demo.a,demo.b,demo.c);//1 2 3



export default 导出的数据,导入的时候不需要{} 



1.js
export default a=10;
2.js
import a from '1.js'
console.log(a)//10



1.js
export default a=10;
export const b=20;
2.js
import a {b} from '1.js'
console.log(a,b)//10 20



import  有提升效果,import会自动提升到顶部,首先执行

导出到模块的内容,如果里面有定时器更换,外面也会改动,不同commonJS的缓存

import() 类似node里面的require,可以动态引入,默认import语法不能写在if之类里面;

import() 可以写在if语句中,可以使用动态路径;路径可以是相对的或者是绝对的;按需加载;返回的是Promise对象可以使用then

demo:



1.js
export const a=10;
export const b=20;
2.js
import('1.js').then(res=>{
    console.log(res.a,res.b);、、10 20
});



结合promise使用

demo:



1.js
export const a=10;
2.js
export cosnt b=20;
3.js
Promise.all([import('1.js'),import('2.js')]).then((mode1,mode2)=>{
    console.log(mode1,mode2);//{a:10} {b:20}
);



class Person{
  constructor(){  //构造函数(方法),调用new,自动执行
  }
}

demo:



class Person{
      constructor(name,age){
         console.log(`构造函数执行了name:${name},年龄:${age}`);
      }
  }
  new Person('zhangsan',18);//构造函数执行了name:zhangsan,年龄:18



es5 模拟类:



let Person=function(name,age){
        this.name=name;
        this.age=age;
    }   
Person.prototype.showName=function(){
    console.log(this.name);
}     
Person.prototype.showAge=function(){
    console.log(this.age);
}



es6定义类



class Person{
      constructor(name,age){
          this.name=name;
          this.age=age;
         console.log(`构造函数执行了name:${name},年龄:${age}`);
      }
      showName(){
          console.log(`name:${this.name}`);
      }
      showAge(){
        console.log(`age:${this.age}`);
    }
  }
  let p=new Person('zhangsan',18);
  console.log(p.showName(),p.showAge());



注意点

1 constructor new时自动调用

2 方法之间没有逗号,间隔

3 方法不能加function关键字

 

类也可以使用变量命名方式



let Person=class{
      constructor(name,age){
          this.name=name;
          this.age=age;
         console.log(`构造函数执行了name:${name},年龄:${age}`);
      }
      showName(){
          return `name:${this.name}`;
      }
      showAge(){
        return `age:${this.age}`;
    }
  }
  let p=new Person('zhangsan',18);
  console.log(p.showName(),p.showAge());



方法可以使用变量名:



let a='showName';
let b='showAge';
class Person{
      constructor(name,age){
          this.name=name;
          this.age=age;
         console.log(`构造函数执行了name:${name},年龄:${age}`);
      }
      [a](){
          return `name:${this.name}`;
      }
      [b](){
        return `age:${this.age}`;
    }
  }
  let p=new Person('zhangsan',18);
  console.log(p.showName(),p.showAge());
console.log(p[a](),p[b]());//与上面的等价


注意点:

es6里面的class没有提升功能,只能先定义再使用,再ES5中,用函数模拟,有提升功能,function本身有提升功能

矫正this

1 fn.call(this指向谁,args1,args2...);
2 fn.apply(this指向谁,args1,args2,...);
3 fn.bind(this指向谁)

 

class里面取值(getter)存值(setter)封装框架会用到

 

静态方法:类身上的方法,直接使用类调用 static,子类可以继承父类的静态方法

demo:



class Person{
      constructor(name,age){
          this.name=name;
          this.age=age;
      }
      static aa(){
          return 'this is aa'
      }
      showName(){
          return `name:${this.name}`;
      }
      showAge(){
        return `age:${this.age}`;
    }
  }
  let p=new Person('zhangsan',18);
  console.log(Person.aa());//this is aa,只能用类进行调用,不能用实例调用



类的继承

extends关键字实现

demo:

class Person{
      constructor(name,age){
          this.name=name;
          this.age=age;
      }
      static aa(){
          return 'this is aa'
      }
      showName(){
        console.log('这是父类的showName方法') 
          return `name:${this.name}`;
      }
      showAge(){
        return `age:${this.age}`;
    }
  }
  class Student extends Person{
      constructor(name,age,skill){
          super(name,age);//继承父类的属性name age
          this.skill=skill;
      }
      showName(){
          super.showName();//继承父类的showName方法
          console.log('这是子类的showName方法') 
      }
      showSkill(){
          return  `技能${this.skill}`
      }
  }
  let stu=new Student('zhangsan',18,'学习');
  console.log(stu.showSkill());
 stu.showName();



1 子类定义自己的contructor需要使用super关键字继承父类的属性,然后可以添加自己的属性

2 字类可以定义与父类一样的名字的方法,直接覆盖父类的方法

3 子类继承父类的方法,并添加自己的方法,需要使用super关键字,先继承父类的方法,再写自己的私有方法,这样先执行父类的方法,再执行子类的方法

新增数据类型

number string object function undefined  bollean

symbol 

1 Symbol不能new

2 Symbol() 返回是一个唯一值,做一个key,定义一些唯一或者私有的东西

3 symbol是一个单独数据类型,就叫symbol基本类型

4 如果symbol作为key,用for in循环,出不来(因为是私有的,不显示)

generator函数

  生成器

解决异步的问题,深度嵌套的问题,现在使用asyns

语法:

function * show(){} 在function和方法名之间有一个*号
yield
demo:



function * gen(){

  yield "welcome";

  yield "to";

  return '牧马人'

}

let g1=gen();

使用方法:

手动调用

g1.next();//{value:'welcome',done:false}

g1.next();//{value:'to',done:false}
g1.next();//{value:'牧马人',done:true}
for...of 自动遍历generator

for(let value of g1){

console.log(value);// welcome to

}



return的东西不会遍历

也可以使用解构赋值

let [a,...b]=gen();//a:'welcome' b:to

console.log(...gen)//['welcome','to']

console.log(...gen)//['welcome','to']

generator一般配合promise使用

async和await

async特点:表示的就是异步,这个函数里面有异步任务

await 表示后面结果需要等待

async特点:

1 await只能放在async函数中

2 await后面可以是promise对象,也可以是数字 字符串

3 相比generator语义化更强

4 async返回的是一个promise对象

5 只要await语句后面Promise状态变成reject,那么整个async函数就会中断执行

async函数中抛出错误,影响后续代码:

1 使用try catch

try{}catch(err){}

2 promise本身就有catch,直接使用catch

demo:



async function demo(){
       await Promise.reject('出错了')
       console.log(await Promise.resolve('success'))
       console.log(await Promise.resolve('success1'))

   }
   demo();



结果:

es 复制索引结构 java_es 复制索引结构 java

出错了,后面的代码不会执行;

使用try catch



async function demo(){
       try{await Promise.reject('出错了')}catch(err){
            console.log(err);
       }
       console.log(await Promise.resolve('success'))
       console.log(await Promise.resolve('success1'))

   }
   demo();



es 复制索引结构 java_es 复制索引结构 java_02

下面的代码依然执行

使用promise的catch



async function demo(){
       await Promise.reject('出错了').catch(err=>{
        console.log(err);
       })
       console.log(await Promise.resolve('success'))
       console.log(await Promise.resolve('success1'))

   }
   demo();



结果同上

使用await的地方一般都是数据请求,都有出错的可能,都需要进行出错检测,建议都放在try catch中



async function demo(){
       try{
           await Promise.reject('出错了');
           await Promise.resolve('success')
           await Promise.resolve('success1')
        }catch(err){
            console.log(err);
       }
       
   }
   demo();



Set WeakSet 

新增的数据结构

Set数据结构,类似数组,但是里面不能有重复值

set的用法:

new Set([]);参数是一个数组 存储的是一个数组

数组去重



let arr=[1,2,3,4,5,1];
   let setArr=new Set(arr);
   console.log(setArr);



es 复制索引结构 java_数据结构与算法_03

转成数组

Array.from(setArr)

let arr2=[...setArr]

set添加值 add

let setArr=new Set();

setArr.add('a');

setArr.add('b');

setArr.add('c');

删除一项元素

setArr.delete('a') 

判断set中是否包含某个值

setArr.has('a')//返回true false
setArr.size 属性,查看个数

setArr.clear()清除所有

可以使用for of进行遍历取值

setArr没有下标

 

WeakSet({}) 存储的是一个json,初始添加json不行,没有size和clear()需要用add添加  不太靠谱

总结:new Set() 不适用weakSet()

map

map:类似json,但是json的键(key)只能是字符串

map的key可以是任意类型

用法:

设置值set 

取值 get

删除元素 delete

是否包含某个元素has(key)

清空clear()

循环:

for of

demo:



let map=new Map();
   let json={a:1,b:2};
   map.set('a','aaa');
   map.set(json,'aaa');
   map.set('aaa',json);
   console.log(map);
   console.log(map.get(json));



WeakMap() 官方文档说的是:key只能是对象

总结:

Set 里面是数组,不重复,没有key,没有get方法

Map 对json功能的增强,key可以是任意类型的值

 

Number

Number.isNaN()判断是否是NaN
Number.parseInt
Number.parseFloat
新增的方法
Number.isFinite()判断是否是数字
Number.isInteger() 判断数字是否是整数
安全整数:
-(2^53-1)~(2^53-1)
Number.isSafeInteger() 判断是否是安全整数
Number.MAX_SAFE_INTEGER  最大安全整数
Number._MIN_SAFE_INTEGER 最小安全整数
 Math
Math.abs()
Math.sqrt()
Math.sin()
Math.cos()

Math.trunc() 截取数据的整数部分



Math.sign(0)  0
Math.sign(-0)  -0
Math.sign(3)  1
Math.sign(-3)  -1
其他值 NaN



Math.cbert()  取一个值得立方值

Math.cbert(27)    3

判断一个数是 正数  负数  0 -0