ES6-11

一、ES6

js的异步和同步,js是单线程语言:

同步:加入主线程,按顺序执行,即上一个同步任务结束后,本任务跟着执行。

异步:加入任务队列,等待主线程上任务都执行完毕,请求主线程后才能执行。

(一)let变量

A、let作用域为块(或者for循环和if while)

javascript 复制代码
 {
    let you = "forever";
  }
  console.log(you);//报错,找不到you,因为you变量在块中。

B、命名一致冲突报错

javascript 复制代码
  //let命名一致冲突报错,但是var不会
  let he = "老大";
  let he = "我会等";//会报错。

C、不存在自动提升(变量声明提升)

javascript 复制代码
//不存在变量自动提升,根据实际出现位置命名变量
   console.log(her);//报错无法找到变量,但是若是var则是undefinded,能够找到变量。
   let her = "Drling";

var的话,会把所有变量放在代码前面声明,到对应行后再赋值,所以如果是var不会报错。

D、点击变换实例

javascript 复制代码
 //获取元素
    let items = document.getElementsByClassName("item");
    //循环遍历
    for(let i = 0; i < items.length;i++){
      items[i].onclick = function(){
        items[i].style.backgroundColor = 'pink';
      }
    }
    console.log("完成!");

这样可以,如果把循环中let换为var,则会出错,因为var是全局作用域,会在函数向外寻找时加至items3,所以找不到元素颜色无法变换。

(二)const变量

A、const作用域也是块,用来定义常量,常量一般大写

javascript 复制代码
//常量声明
    const ONE = 'go';

B、声明时必须赋值,而后不可更改

javascript 复制代码
//不能修改(否则报错)
    const TWO = 'thyShy';
    //const TWO = 'xiaohu';修改已定义常量,报错。因为常量指向变化

C、数组常量可以改,因为指向不变

javascript 复制代码
const THREE = ["kuisang","永恩"];
    THREE.push("凯隐");//不会报错,指向没变
    console.log(THREE);

(三)解构赋值

解构赋值允许按照一定规则,从数组或者对象中提取数值,赋给变量。

A、数组解构赋值

javascript 复制代码
//数组结构赋值(根据顺序)
    const me = ['大头儿子','小头爸爸','一休'];
    let[you,he,her] = me;
    console.log(you + he + her);

B、对象解构赋值

javascript 复制代码
//声明对象
const him = {
       name : '赵子龙',
       sex : '男',
       kill : function(){
        console.log('七进七出,骁勇善战');
       }
    }
    //根据变量名提取,不能随便改名。
    let{name,sex,kill} = him;
    console.log(name + sex + kill);
    kill();//调用

(三)字符串新声明方式`

A、声明

javascript 复制代码
//声明
  let four = `这首歌是写给黄淮。`;

B、允许换行

javascript 复制代码
//可以使用换行
  let five = `<ul>
          <li>天使</li>
          <li>魔鬼</li>
          <li>上帝</li>         
    </ul>`;
    //若换成'或者"则报错,不允许换行。

C、字符串拼接

javascript 复制代码
//字符串拼接
    let six = `黄淮`;
    let seven = `写给${six}`;
    console.log(seven);

不同于之前使用+号拼接,这里使用${}。

(四)对象属性声明简化书写

如果对象的属性名要赋已经声明的变量,且变量名和属性名一致,则省写冒号和赋值;

对象中声明函数也可以简化为:函数名(){};

javascript 复制代码
 let myName = '托尼斯达克';
    let myGo = function(){
      console.log("fly");
    }
    const myObject = {
         myName,//之前,myName:myName
         myGo,
         myLove(){
          console.log('she love me too!');
         }//之前 myLove:function(){}
    }
    //验证
    console.log(myObject.myName);
    myObject.myGo();
    myObject.myLove();

(五)函数声明的简化(箭头函数)

A、简化书写

javascript 复制代码
const functionTest = (a,b,c) => {
       return a + b - c;
  }
  let num = functionTest(4,5,1);
  console.log(num);

B、this指向始终不变

简化函数声明中的this始终指向函数声明时所在的作用域所在的this下的值,例如在函数A中声明的函数B中的this就始终指向函数A,在对象中或者直接声明的函数始终指向window对象。

javascript 复制代码
  //1、this始终指向自声明后,始终如一。
 window.name="我是windows";
  
  const myCloud = {
        name:"我是myCloud对象的云",
         testOne : function(){
    console.log(this.name);
  },//原来方式声明
   testTwo:()=>{
    console.log(this.name);
  }//简化方式声明
  }
  
  myCloud.testOne();
  myCloud.testTwo();
  //用call改变this指向,后原始方式变化,简化方式不变。
  myCloud.testOne.call(window);
  myCloud.testTwo.call(window);

输出结果:

即使用call函数改变testTwo使其指向myCloud也没有用,一直是window。

javascript 复制代码
myCloud.testTwo.call(myCloud);//我是windows

C、不能作为构造函数构造实例化对象

javascript 复制代码
/不能构造实例化对象
  let youTestFun = (a,b)=>{
      this.a = a,
      this.b = b
  }
  const meTestFun = new youTestFun("我","你");//报错

我认为,还是跟this指向固定不变有关,所以在构造过程中无法动态变化赋值。

D、不能使用arguments参数

不能使用函数默认参数arguments。(注:非简化声明的函数存在arguments用来承接未声明但在实际调用中多出来的参数。)

javascript 复制代码
//不能使用arguments
  let youTestFunOne = ()=>{
      console.log(arguments);
  }
  youTestFunOne("me");//报错找不到arguments

不使用简化方式:

javascript 复制代码
let youTestFunOne = function(){
      console.log(arguments);
  }
  youTestFunOne("me");//结果为arguments["me"]

E、箭头函数简化

当声明的函数只有一个参数或者函数中语句只用一句时,可以对箭头函数进行再简化,可以省略括号或花括号且那一条语句不需要return,默认为将结果作为返回值。

简化前:

javascript 复制代码
let meTestFunh= (n) => {
      return n + 1;
  }
  let heMe = meTestFunh(9);
  console.log(heMe);

简化后:

javascript 复制代码
let meTestFunh= n => n + 1;
    let heMe = meTestFunh(9);
  console.log(heMe);

F、实际应用

实践一:

javascript 复制代码
 //需求,点击块后,2s后变色。
  let chCon = document.getElementsByClassName("changeColorContain");
  let chCoCon = chCon[0];
  chCOCon.addEventListener("click",function(){
         setTimeout(function(){
          this.style.backgroundColor= "blue";
          //这里this指向调用者windows,而window无style,会报错。
         }, 2000);
  });

修改一:this传导到元素

javascript 复制代码
  //需求,点击块后,2s后变色。
  let chCon = document.getElementsByClassName("changeColorContain");
  let chCoCon = chCon[0];
  chCoCon.addEventListener("click",function(){
        let _this = this;
         setTimeout(function(){
          _this.style.backgroundColor= "blue";
           //------this往上找找到this,而上面this指向元素chCoCon。
         }, 2000);
  });

修改二: 通过箭头函数,指向所在所用域下this的值,即(元素chCoCon)

javascript 复制代码
 //需求,点击块后,2s后变色。
  let chCon = document.getElementsByClassName("changeColorContain");
  let chCoCon = chCon[0];
  chCoCon.addEventListener("click",function(){
        
         setTimeout(()=>{
          this.style.backgroundColor= "blue";
         }, 2000);
  });

实践二:

javascript 复制代码
//从数组中筛选出2的偶数
  const numSub = [2,3,53,88,100,23];
   const result = numSub.filter(function(item){
      if(item % 2 == 0){
        return true;
      }else{
        return false;
      }
   })
   console.log(result);

改进:

javascript 复制代码
 //从数组中筛选出2的偶数
  const numSub = [2,3,53,88,100,23];
   const result = numSub.filter(item=> item % 2 == 0)
   console.log(result);

(六)参数赋默认值

A、简单参数赋默认值

javascript 复制代码
const skyFun = (a,b,c,d=10)=> a + b + c + d;
  //不给值,有默认值就是默认值,否则undifinded
  let numSkey = skyFun(3,54,3);//70
  let numSky = skyFun(1,2,3,9);//15
  console.log(numSkey + " " + numSky);

B、对象型参数中属性赋默认值

如果函数中传入参数是对象,则要先将对象写成参数解构形式,然后赋默认值。

javascript 复制代码
//和解构赋值结合使用
  let outBody = ({name,sex,age=18})=>{
    console.log("刚满" + age + "岁~");
  }
  const myLove = {
    name: '老爹',
    sex: '男',
    age: 20
  }
 outBody(myLove);//传入对象,age有值为20;
 outBody({name:"爱人",sex:"女"});//传入对象,无age,使用默认值18。

(七)rest参数

A、ES5和ES6对比

javascript 复制代码
//ES5可变参数接收
   let myChangeFun = function(){ console.log(arguments);};
   myChangeFun("萧炎","荒天帝","美杜莎","七彩吞天蟒");//arguments以对象形式保存
   //ES6可变参数接收
   let myChangeFunTwo = (...args)=> {console.log(args);};                          
  myChangeFunTwo("萧炎","荒天帝","美杜莎","七彩吞天蟒");//该风格,以数组形式保存。

结果展示:

(八)扩展运算符

A、功能

可以将数组中的元素变为以逗号隔开的参数序列:

javascript 复制代码
//扩展运算符
  let myArray = ["萧炎","荒天帝","美杜莎","七彩吞天蟒"];
  let showMy = function(){console.log(arguments)};//是一个参数,类型是数组。
  //正常传参数,数组,1个参数
  showMy(myArray);
  //用扩展运算符,变量,4个参数
  showMy(...myArray);
  

B、数组合并

javascript 复制代码
//利用扩展运算符合并
  let myArrayThree = [...myArrayOne,...myArrayTwo];
  console.log(myArrayThree);
  

C、将伪数组变为真数组

变为数组后可以使用数组的一些方法

javascript 复制代码
  //伪数组
  let divs = document.querySelectorAll("div");
  //真数组
  let myDivs = [...divs];
  console.log(divs);
  console.log(myDivs);

D、数组的克隆

javascript 复制代码
   let one = ["邓紫棋"];
   let two = ["hh"];
    two = [...one];
   console.log(two);

这种克隆是浅拷贝,基本类型复制值,引用类型复制引用地址,指向同一个值,新对象(引用类型)会影响原对象。即是说,当复制的数组中还有数组,就是复制最里层数组地址。

(九)Symbol

Symbo是ES6中新出现的基本数据类型,是继前五大数据类型(字符串,null,undefinded,Object,num(数字),布尔)后出现的第六大数据类型。

因为对象中的键值在ES5中只能使用字符串,会存在key值冲突的风险,尤其是当合作过程中拿到一个陌生的对象,很容易在添加方法过程中导致key重复。故而Symbol诞生,它的特点就是唯一,即使在利用Symbol中函数生成同样字符串,也是不同键值,相等运算为false。

A、为对象添加方法的两种方式

javascript 复制代码
//symbol()的使用
  let rabbit = {
    name: '小白兔',
    age: 18,
    skip(){
      console.log("唱跳rap");
    },
    eat(){
      console.log("吃的很多!");
    }
  }
   //作用一:防重复key命名
   //方式一:
   let model = {
     skip: Symbol(),
     eat: Symbol()
   }
   rabbit[model.skip] = function(){
      console.log("新增skip方法");
   }
   rabbit[model.eat] = function(){
     console.log("新增的吃方法");
   }
   console.log(rabbit);
   //方式二
   let tigger = {
     name:"微少",
     age: 20,
     [Symbol("fly")](){
      console.log("轰轰轰!");
     },
     [Symbol("fly")](){
       console.log("哈哈哈");    
     }
   }
   console.log(tigger);
   

B、Symbol的特点

  1. 不能和其他数据类型进行运算,包括字符串拼接。
  2. 在对象中声明的Symbol类型的key,在循环遍历对象过程中是透明的。

C、Symbol的内置属性

作为一种基础数据类型,在作为唯一键值称为对象中的属性,也可以在声明对象属性时调用内置属性生成对象的key值,这些key下的属性或者方法会在特定时机被调用。

  • Symbol.hasInstance

当属性对应的类被作为instanceof的对象时,其对应方法会被自动调用

javascript 复制代码
//Symbol内置属性
   class people{
    static[Symbol.hasInstance](){
         console.log("我是Symbol.hasInstance作为键值的方法,我被自动调用了");
    }
   }
   let Bob = {};
   //当people被用于 instanceof 时,该方法会被自动调用
   Bob instanceof people;

运行结果:

还有很多内置属性,可以搜索查看,基本都是在特定情况下,自动调用某种函数。

(十)Iterator(迭代器)

ES6引入迭代器接口,只要实现了迭代器接口的数据类型,就可以使用for.....of....循环语法。

A、默认实现迭代器的数据结构类型

Array、Arguments、Set、Map、String、TypedArray、NodeList

Array使用迭代器演示:

javascript 复制代码
//iterator迭代器,默认实现迭代器的结构
  let red = ["红","蓝","白","紫","天下"];
  for(let zi of red){
    console.log(zi);//of 展示内容
  }
  for(let wo in red){
     console.log(wo);//in 展示下标
  }

B、迭代器原理

  1. 首先创建一个指针对象指向当前数据结构的起始位置
  2. 执行指针对象中的next方法,指向数据结构的第一个成员;
  3. 不断执行next方法,不断指向下一个结构,返回数据。
  4. 返回数据结构类型为一个属性为value和done的对象,done为false时会一直执行next函数,知道done为true。
javascript 复制代码
let red = ["红","蓝","白","紫","天下"];
  let myIterator = red[Symbol.iterator]();
  for(let i = 0; i <= red.length;i++){
       console.log(myIterator.next());
  }

C、自定义迭代器

javascript 复制代码
let contain = {
        name: 'shao杰',
        lover:["米老鼠","柯洁","tiancai","小八嘎" ],
        [Symbol.iterator](){
          let index = -1;
          let _this = this;
          return{
                 next(){
                     if(index == -1){
                         index++;
                        return {value: _this.name,done: false}
                     }else if(index<_this.lover.length - 1 && index != -1){
                      index++;
                        return {value:_this.lover[index],done:false}
                     }else{
                      return {value:_this.lover[index],done:true};
                     }
                 }     
            }            
        }  
  }
 for(let one of contain){
      console.log(one);
 }

(十二)生成器

A、一种特殊的函数(生成器)

生成器函数返回的是一个迭代器对象,通过调用next方法执行其中语句,yield语句相当于暂停标志,每次next,执行一段代码,后返回yield语句后内容

javascript 复制代码
//生成器函数
 function * lover(){
    console.log("one,我是天选也是唯一"); 
    yield "one",
    console.log("冲天香阵透长安");
     yield "two",
     console.log("i am iron man");
     yield "three"
}
//调用生成器函数
room = lover();
room.next();//每次调用都会执行一个yield之前的句子,并返回yield后数据。
room.next();

B、传参

  • 生成器传参
javascript 复制代码
//生成器函数
 function * lover(param,me){
    console.log(param + "我爱你!" + me);
    yield "one",
    console.log("冲天香阵透长安");
     yield "two",
     console.log("i am iron man");
     yield "three"
}
//调用生成器函数
room = lover("美女","我");
room.next();//每次调用都会执行一个yield之前的句子,并返回yield后数据。
  • next传参

next中传入的参数会作为上一个yield语句的返回值。

javascript 复制代码
//生成器函数
 function * lover(){
    console.log("我爱你!");
    let oneReturn = yield "one";
    // 这里返回的是上一个yield的返回值
    console.log("上一个yield的返回值是" + oneReturn);
     yield "two";
     console.log("i am iron man");
     yield "three"
}
//调用生成器函数
room = lover();
let reture = room.next();//每次调用都会执行一个yield之前的句子,并返回yield后数据。
console.log(reture);
room.next("你好老弟");
room.next();

C、简化异步函数调用

原方式:(每步应该添加定时器,这里省略了)

javascript 复制代码
function getOrder(){
    let data = "订单数据";
    console.log("获得了订单!");
    return data;
}
function getCust(){
    let dataUp = getOrder();
    let data = "顾客信息";
    console.log("获得了订单数据:" + dataUp + "顾客信息。");
    return data + dataUp;
}
function getAll(){
     let dataUp = getCust();
    let data = "全部信息";
    console.log("获取了全部" + data + dataUp);
    return dataUp + data;
}

getAll();

使用生成函数:(这里每一步必须使用定时器,否则报错!)

javascript 复制代码
function getOrder(){
    setTimeout(()=>{
        let data = "订单数据";
    zongzi.next(data);//调用下一步,并为OrderData赋值;
    },2000)
    
}
function getCust(){
    setTimeout(()=>{
    let data = "顾客信息";
    zongzi.next(data);
    },2000)
    
}
function getAll(){
    setTimeout(()=>{
    let data = "全部信息";
    zongzi.next(data);
    },2000)
    
}
function * myTest(){
    let OrderData = yield getOrder();
    console.log("拿到了订单数据" + OrderData);
    let CustData = yield getCust();
    let CuOrData = CustData + OrderData;
    console.log("拿到了订单和客户数据" + CuOrData);
    let allData = yield getAll();
    let zongInfo = allData + CuOrData;
    console.log("拿到所有数据" + zongInfo);    
}
let zongzi = myTest();
zongzi.next();

(十三)Promise

A、使用

javascript 复制代码
//两个参数,名称随意,都是函数,第一个成功时调用,改变testOne状态为成功。
//第二个失败时调用,改变testOne状态为失败。
let testOne = new Promise(function(get,reject){
    setTimeout(()=>{
        //一、错误情况
        // console.log("一堆逻辑");
        // console.log("有错误出现");
        // error = "计算有误";
        // reject(error);//传入错误的原因,参数。
        //二、成功情况
        value = "太酷了";
        get(value);
    })
})
// then两个参数,第一个函数状态为成功执行,第二个状态为失败执行。
testOne.then((value)=>{
        console.log("执行成功,获取到的数据为" + value);        
},(error)=>{
    console.log("错误的原因是" + error);
    console.log("一堆对出现错误后的处理逻辑");
})

B、实例(读取文件内容到控制台)(要用到node.js)

  • 不使用Promise
javascript 复制代码
//读取文件到控制台
const fs = require('fs');
fs.readFile("./test.txt",(error,data)=>{
    if(error)throw error;//出错的逻辑
    console.log(data.toString());
})
  • 使用Promise
javascript 复制代码
//读取文件到控制台
const fs = require('fs');
// fs.readFile("./test.txt",(error,data)=>{
//     if(error)throw error;//出错的逻辑
//     console.log(data.toString());
// })
let myPromise = new Promise(function(get,back){
      fs.readFile("./test.txtm",(error,data)=>{
        if(error){
            back(error);//传入原因
        }else{
            get(data);
        }
      })
});
myPromise.then((data)=>{
    console.log(data.toString());
},(error)=>{
    console.log(error);
});

(十四)Set集合

A、特点:可使用扩展运算符,不允许重复(自动去重)

javascript 复制代码
//Set集合,不可重复
let mySet = new Set([1,1,2,2,3,4,3,2]);
//添加元素
mySet.add(0);
//删除元素
mySet.delete(1);
//返回元素个数
let all = mySet.size;
console.log(mySet + "总数是" + all);
//判断是否存在某元素
console.log(mySet.has(0));
//转化数组,因继承Interator接口,所以可以使用扩展运算符和for...of
let arrayMe = [...mySet];
console.log(arrayMe);
//遍历
for(let i of mySet){
   console.log(i);
}
//清空Set
mySet.clear();
console.log(mySet);

结果:

B、集合操作

javascript 复制代码
//集合操作
let oneArr = [1,1,2,2,3,3,0,0,4];
let twoArr = [4,4,5,5,3,6,6];
//交集
let oneSet = new Set([...oneArr]);//去重
let twoSet = new Set([...twoArr]);
let resultSet = [...oneSet].filter((item)=> twoSet.has(item));
console.log(resultSet);
//并集
let resultSetTwo = new Set([...oneArr,...twoArr]);
console.log(resultSetTwo);
//差集
let resultSetThree = [...oneSet].filter((item) => !twoSet.has(item));
console.log(resultSetThree);

结果:

(十五)Map

Map很像对象,里面是键值对的数据结构,和对象不同,任何类型(包括对象)都可以成为Map的键值,继承了Interator接口,可以使用扩展运算符和for...of..语句。

javascript 复制代码
//Map
let myMap = new Map();
myMap.set("姓名","道发");
myMap.set([1,2,3],"哈哈");
let object = {
    name: "唧唧",
    age: 18
}
myMap.set(object,"我爱你!");
for(let o of myMap){
    console.log(o);
}

(十六)Class

Class是对象的一种规范和模版,简化了之前声明构造函数的过程,采用更易理解的方式声明对象的模版。

javascript 复制代码
//声明构造函数
function people(name,lover){
    this.name = name;
    this.lover= lover;
}
//添加方法
people.prototype.sayLove = function(){
    console.log(this.lover + "我爱你!");
}
//创建对象,调用方法
let onePeople = new people("杜若衡","天流芳");
onePeople.sayLove();
//现创建Class
class PP{
   //构造方法,new对象时会自动调用
    constructor(name,lover){
    this.name=name;
    this.lover=lover;
   }
   //函数声明固定格式,不可为name:function()方式
   sayLove(){
    console.log(this.lover + "我爱你!");
   }
}
//创建对象,调用方法
let PPOne = new PP("琉璃月","陌上桑");
PPOne.sayLove();

A、静态成员

只属于类或者构造函数的属性或者函数。

javascript 复制代码
//静态成员
//构造函数的静态成员
function wo(){    
}
//下面的属性属于构造函数,不属于对象。
wo.name = "郦道元";
wo.age = 18;
wo.prototype.trueName="你";
let woOne = new wo();
//class的静态成员
class hi{
     static name = "郦道元";
     static age = 18;
     trueName = "你";
    constructor(){

    }
}
let hiOne = new hi();
console.log(wo.age);
console.log(hi.age);
//对象和构造函数的原型中属性相通,和在其内部直接声明的属性。
console.log(woOne.trueName);
console.log(hiOne.trueName);
console.log(woOne.age);//undefined
console.log(hiOne.age);//undefined

B、get和set

get和set后面跟属性名,当要获取该属性就会调用get函数,当要修改就会调用set函数,注意不要返回自身,不然会陷入循环调用地狱。

javascript 复制代码
class People{
    myPrice;
    constructor(first,end){    
        this.first = first;
        this.end = end;    
    }
    
    get price(){
        this.myPrice = this.first + this.end;
        return this.myPrice;
         
    }
    set price(value){
        this.myPrice = value;
         return myPrice;
    }
}
  let hei = new People(1000,800);
  let wo = hei.price;
  console.log(hei.price);会调用get

(十七)继承

A、构造函数继承

javascript 复制代码
//继承
function Phone(band,type){
    this.band = band;
    this.type = type;
}
Phone.prototype.say = function(){
    console.log("我是" + this.band + "牌子的" + this.type);
}
function SmartPhone(band,type,price,color){
     Phone.call(this,band,type);
     this.price = price;
     this.color = color;
}
//将子构造函数原型指向父类的原型,继承父类的方法
SmartPhone.prototype  = Phone.prototype;
//创造对象检查
let SmartTrue = new SmartPhone("锤子","智能手机",1000,"红色");
SmartTrue.say();
console.log(SmartTrue);

B、类的继承

javascript 复制代码
class Phone{
    constructor(band,type){
        this.band = band;
        this.type = type;
    }
    say(){
        console.log("我是" + this.band + "的" + this.type);
    }       
}
class SmartPhone extends Phone{
    constructor(band,type,price,color){
          super(band,type);
          this.price = price;
          this.color = color;
    }
       //新增方法
       speak(){
        console.log("我是" + this.band + "手机,我为自己代言!");
       }
} 
//声明对象并尝试
let myPhone = new SmartPhone("苹果","智能手机",4900,"红色");
myPhone.say();
myPhone.speak();

C、重写

截取上面例子的子类展示重写

javascript 复制代码
class SmartPhone extends Phone{
    constructor(band,type,price,color){
          super(band,type);
          this.price = price;
          this.color = color;
    }
       //新增方法
       speak(){
        console.log("我是" + this.band + "手机,我为自己代言!");
       }
       //重写方法
       say(){
          console.log("我是重写后的方法");
       }
} 
//声明对象并尝试
let myPhone = new SmartPhone("苹果","智能手机",4900,"红色");
myPhone.say();
myPhone.speak();

(十九)Number和Math的属性方法

javascript 复制代码
 //1、Number
  Number.EPSILON;//该属性是Number计算的最小误差,通过该属性改变比较结果。
  function equal(a,b){
    if(a - b < Number.EPSILON){
          return true;
    }else{
        return false;
    }
  }
  let a = 0.2;
  let b = 0.5;
  console.log(equal((a+b),0.7));
//2、判断有限数,是为true,不是为false
console.log(Number.isFinite(100/0));//false
console.log(Number.isFinite(34));//true
console.log(Number.isFinite(Number.PI))//false
//3、判断数的正负,正为1,负为-1,0为0
console.log(Math.sign(3));
console.log(Math.sign(-3));
console.log(Math.sign(0));
//4.判断是否NaN
console.log(Number.isNaN(100/0));
console.log(Number.isNaN("天"));
//5.将字符串转化为数值
console.log(Number.parseInt("1243544"));
console.log(Number.parseFloat("1.23344"));
//6.判断一个数是否为整数
console.log(Number.isInteger(45));
console.log(Number.isInteger(2.133));
//7.将浮点数的小数部分抹去
console.log(Math.trunc(2.99));//默认下舍入

(二十)对象方法扩展

A、Object.is(A,B)

判断A和B两个数是否完全相等,和===功能相似,但是对NaN之间比较的判断结果不一,is为true,===为false。

javascript 复制代码
let one = Object.is(2,2);//相当于===,判断两个数是否完全相等。
//例外,NaN对于===是faluse,对于is来讲是true;
console.log(one);
console.log(Object.is(NaN,NaN));

B、Object.assign(A,B)

令对象B中内容,根据同key覆盖进行覆盖,覆盖对象A中的属性。对于属性A中没有属性B中存在的属性,在A中增加,对于A中存在,但B中不存在的属性,保持不变。

javascript 复制代码
let ObOne = {
    name: "小天才",
    age: 18,
    fly(){
        console.log("小天才飞上天了!");
    },
    mySelf: "我独苗"
}
let ObTwo = {
    name: "大猪蹄子",
    age: 20,
    fly(){
        console.log("大猪蹄子飞上天了");
    },
    he:"别浪"
}
//让后者覆盖前者
 Object.assign(ObOne,ObTwo);
console.log(ObOne);

C、插入原型链(一般不用)

javascript 复制代码
let me = {
    name: "我",
    age: 19
}
let you = {
    name: "你",
    age: 20,
    say(){
        console.log("你看着我眼睛~");
    }
}
//将后者作为前者的原型对象(插入原型链)
Object.setPrototypeOf(me,you);

(二十一)模块化

A、什么是模块化

ES5时我们引入js文件,每个js文件中的变量不能出现命名冲突,这样就导致很多麻烦,所以引入模块化,也适用于大型项目的合作开发。

模块化的好处有:防止命名冲突、方便代码复用、维护升级方便。

B、暴露与引用

模块之间要相互调用,就要用到暴露和引用语法,我们用一个js文件来代表一个模块。

因为要用不同文件,所以要解决跨域问题,这个问题可以用Live Server插件来解决,下载之后,在vs code右下角打开,然后在文件中右击,选择用live Server运行,那么该插件会自动扮演一个代理服务器,这样就能够解决跨域问题了。

  • 暴露
javascript 复制代码
export const name = "jack";
export const rose ={
    name: "rose",
    age: 20,
    say(){
        console.log("i love you jack!");
    }
}
//export是分别暴露。
  • 引入
javascript 复制代码
<script type="module">
//引入
import *  as a from "./testAgain.js";
//引入后暴露属性都被加入a中,通过a来调用。
console.log(a.name);
console.log(a);
</script>

结果:

C、其他暴露方式

  • 统一暴露
javascript 复制代码
 const name = "jack";
 const rose ={
    name: "rose",
    age: 20,
    say(){
        console.log("i love you jack!");
    }
}
//统一暴露
export{
    name,rose
}
  • 默认暴露
javascript 复制代码
 export default{ 
  name : "jack",
  rose:{
    name: "rose",
    age: 20,
    say(){
        console.log("i love you jack!");
    }
}
 }

引用方式也要发生变化,因为默认方式相当于在中间又加了个对象。

javascript 复制代码
<script type="module">
//引入后暴露属性都被加入a中,通过a来调用。
console.log(a.default.name);
console.log(a.default);
</script>

D、其他引入方式

  • 针对默认暴露
javascript 复制代码
//a 直接为default的别名
import a from "./testAgain.js";
//解构赋值,设置别名
import {default as a} from "./testAgain.js";
  • 针对统一暴露
javascript 复制代码
//引入后直接,变为属性值使用,可用as设置别名
import {name,rose} from "./testmoren.js";

E、主模块

当模块过多时,我们可以使用主模块使解构更加清晰,如上有testAgain.js和testmoren.js,这时再增加主模块(app.js),在主模块中使用引用语句。

  • app.js
javascript 复制代码
import {name,rose} from "./testmoren.js";
import {default as me} from "./testAgain.js";
console.log(me);
console.log(name);
console.log(rose);
  • html文件中引入
javascript 复制代码
<script src="./app.js" type="module">
</script>

F、新版本引入模块和包的方式

javascript 复制代码
  import $ from 'jquery';
    //原方式:let jquery = require('jquery');

二、ES7

(一)includes丰富indexOf

includes检测数组是否含有某元素返回的是布尔值。indexof返回的是1或者-1。

javascript 复制代码
    let array = ["红楼梦","大闹天宫","西厢记"];
    console.log(array.includes("金瓶梅"));
    console.log(array.indexOf("高老头"));

(二)** 代替Math.pow

javascript 复制代码
    console.log(Math.pow(2,20));
    console.log(2 ** 20);

三、ES8

(一)async函数

async函数是返回值是Promise对象,Promise对象中的状态根据函数返回情况不同而不同。

A、返回非Promise值,则Promise对象的状态(status)为fulfilled(成功)

函数返回值填充Promise对象的result部分。

javascript 复制代码
async function me(one,two){
         return "我会等";
    }
    let hi = me();
     console.log(hi);

B、return是Promise对象,则返回Promise状态视情况而定

Promise的失败调用函数传参或成功调用函数传参,作为返回Promise的result。

Promise的执行结果作为返回Promise的status

javascript 复制代码
 async function me(one,two){
        let PromiseMe = new Promise((fulfilled,reject)=>{
            if(one == 1 && two == 2){  
            fulfilled("执行成功");
           }else {
            reject("执行失败!");
           }}
        ); 
        return PromiseMe;
    }
     console.log(me(1,2));
     console.log(me(1,1));

(二)await指令

await指令只能出现在async函数体中,await指令后跟返回值为Promise对象的函数,如果Promise对象status为成功,则await返回result,Promise对象status为失败,则直接抛出错误。

A、使用

javascript 复制代码
        function mid(one,two){
            let PromiseMe = new Promise((fulfilled,reject)=>{
            if(one == 1 && two == 2){  
            fulfilled("执行成功");
           }else {
            reject("执行失败!");
           }}           
        ); 
        return PromiseMe;
        }
    async function me(one,two){
        try{
        let winRe = await mid(one,two);//成功后返回结果
        console.log(winRe)
        }catch(error){
        console.log(error);
    }
    }
     me(1,2);
     me(1,1);

B、实例读取文件

javascript 复制代码
 const fs = require('fs');
    function getFile(path){
        return new Promise((fulfilled,reject)=>{
             fs.readFile(path,(err,data)=>{
                   if(err) reject("出错了!");
                   fulfilled(data.toString());
             })
        })
    }
    async function mid(path){
        try{
        let result = await getFile(path);
        console.log(result);
        }catch(err){
            console.log(err);
        }
    }
    mid("./test.txt");

C、实例(用ajax发送请求)

javascript 复制代码
   function sendAJAX(){
        return new Promise((fulfilled,reject)=>{
        let ajax = new XMLHttpRequest();
        ajax.open("get","https://api.xygeng.cn/one");
        ajax.send();
        ajax.onreadystatechange = function(){
            if(ajax.readyState == 4){
                if(ajax.status >= 200 && ajax.status <=399){
                      fulfilled(ajax.response);
                }else{
                    reject(ajax.status);
                }
            }
        }
        })
    }
    async function sendA(){
        let content = await sendAJAX();
        console.log(content);
    }
    sendA();

(三)对象方法扩展

A、遍历对象的方法

javascript 复制代码
const obj = {
        name: "令斛楚",
        age: 20,
        lover:["清漪","美杜莎","傻妞"],
        do(){
            console.log("fly");
        }
    }
    //返回对象键值构成的数组
    const objKeyArr = Object.keys(obj);
    //返回对象属性值构成的数组
    const objValueArr = Object.values(obj);
    //返回对象属性和键构成的键值对
    const objKVArr = Object.entries(obj);
   //变为Map集合
    const objToMap = new Map(objKVArr);
    console.log(objKeyArr);
    console.log(objValueArr);
    console.log(objKVArr);

B、获取对象的描述对象

描述对象中规定了更清晰的属性描述,包括value,可写(writed)、可配置(configurable)、可枚举(enumerable)。

通过Object.create()方法创建的对象,必须制定描述细节属性。

javascript 复制代码
const obj = {
        name: "令斛楚",
        age: 20,
        lover:["清漪","美杜莎","傻妞"],
        do(){
            console.log("fly");
        }
    }
        let objDes = Object.getOwnPropertyDescriptors(obj);
        console.log(objDes);
        //第一个参数是要继承的对象,第二个是新创建的对象结构
        let obj2 = Object.create(null,{
            name:{
                value: "卞之琳",
                writable: true,
                configurable: true,
                Enumerable: true               
            }
        })
    console.log(obj2);

四、ES9

(一)对象使用Rest语法和扩展运算符

A、Rest语法

javascript 复制代码
function getObjProperty({name,age,...other}){
        //当传入对象的一些属性没被显示标出,就会被存入other
        console.log(name);
        console.log(age);
        console.log(other);

    }
    const obj = {
        name: "令斛楚",
        age: 20,
        lover:["清漪","美杜莎","傻妞"],
        do(){
            console.log("fly");
        }
    }
    getObjProperty(obj);

B、扩展运算符

javascript 复制代码
function getObjProperty({name,age,...other}){
        //当传入对象的一些属性没被显示标出,就会被存入other
        console.log(name);
        console.log(age);
        console.log(other);

    }
    const obj = {
        name: "令斛楚",
        age: 20,
        lover:["清漪","美杜莎","傻妞"],
        do(){
            console.log("fly");
        }
    }
    const obj2 = {
        name2: "风清扬",
        age: 23
    }
    //将对象拆解到新的对象。
     let objArr = {...obj};
     console.log(objArr);  
     //合并对象到新的对象,如果有属性名冲突,则后面覆盖前面
     let objArr2 = {...obj,...obj2};
     console.log(objArr2); 

(二)正则表达式的命名捕获分组

A、原方式:保存在数组中

javascript 复制代码
let zongUrl = '<a href="https://baidu.com">尚</a>';
     let ZZ = /<a href="(.*)">(.*)<\/a>/;
     //接收正则表达式接收到的数据,小括号是子正则
     let result = ZZ.exec(zongUrl);
     console.log(result[0]);
     console.log(result[1]);
     console.log(result[2]);
     console.log(result);

B、现方式:直接键值对,预防正则变动导致结构下标变动

javascript 复制代码
    let zongUrl = '<a href="https://baidu.com">尚</a>';    
    let ZZ2 = /<a href="(?<url>.*)">(?<content>.*)<\/a>/;
     let result2 = ZZ2.exec(zongUrl);
    console.log(result2.groups.url);
    console.log(result2.groups.content);

(三)正向断言与反向断言、dotall模式

A、正向断言

判断筛选内容后面是否满足条件:

javascript 复制代码
let love = "1314521冲锋888杀呀";
     //如果数字会随机变化,并且筛选后面为杀的数字。
     let outSha = /\d+(?=杀)/;
     let end = outSha.exec(love);
     console.log(end);

B、反向断言

判断筛选内容前面是否满足条件:

javascript 复制代码
let love = "1314521冲锋888杀呀";
let forContent = /(?<=锋)\d+/;
     let end2 = forContent.exec(love);
     console.log(end2);

与上结果一致。

C、dotAll模式

javascript 复制代码
let text = `<li>
               <a>天下无双</a>
               <p>2022/12/01</p>
                </li>
               <li>
               <a>冲天</a>
               <p>2003/11/23</p>
               </li>`;
    //原来方式:用\s+匹配换行和空格
    let ZZ = /<li>\s+<a>(.*?)<\/a>\s+<p>(.*?)<\/p>/;
    console.log(ZZ.exec(text));
    //现在使用dotAll模式,用.除换行外的任何匹配任何字符
    let ZZ2 = /<li>.*?<a>(.*?)<\/a>.*?<p>(.*?)<\/p>/s;
        console.log(ZZ2.exec(text));

五、ES10

(一)Object.fromEntries

javascript 复制代码
//Object.fromEntries 用键值类型数组元素或者map构造对象
    let you = Object.fromEntries([["name","陈旺财"],["age",19],["lover","托尼"],["you","你"]]);
    console.log(you);
    //与上一个过程相逆
    let me = Object.entries(you);
    console.log(me);

(二)字符串清除空格

javascript 复制代码
    //trimstart清除字符串开头空格 trimend 清除字符串后面空格
    let me = "      i love you   ";
    console.log(me.trimEnd());
    console.log(me.trimStart());

(三)数组方法扩展

javascript 复制代码
 //数组方法扩展
    let arr = ["我是谁","我是天王老子","哈哈",['天下有约',"哈哈"]]
    //将二维数组展开为一维数组
    let chong = arr.flat();
    console.log(chong);
    //flatMap当要遍历的数组中有元素有多维数组,用此函数遍历可以将元素自动降维。每次遍历都会
    //执行一个回调函数
    //map函数也是每次执行一个回调函数,但是不会自动降维。
    let resultMe=arr.flatMap(item => [item]);
   let resultYou =  arr.map(item => [item]);
   console.log(resultMe);
   console.log(resultYou);   

(四)Symbol获取描述字符串

javascript 复制代码
let mySymbol =  Symbol("哇哈哈");
   let bin = mySymbol.description; 
   console.log(bin);

六、ES11

(一)类(class)的私用属性

javascript 复制代码
//为类添加私有属性
   class myName{
    //公有属性  
    name = "天下";
    //私有属性,仅函数内部能够调用
    #age = 19;
    constructor(name,age){
        this.#age = age;
        this.name= name;
    }
    say(){
        console.log(this.name + "" + this.#age);
    }
   }
   let trueName = new myName("冲天",19);
   trueName.say();
   console.log(trueName.age);//undefined,私有属性无法外部使用

(二)Promise.allSettled()

批量执行Promise:

javascript 复制代码
//批量执行Promise
   let myPromiseOne = new Promise((win,reject)=>{
         setTimeout(()=> {win("成功获取数据1!");},1000);
   })
   let youPromiseTwo = new Promise((win,reject)=>{
         setTimeout(()=>{reject("获取数据失败!");},1000);
   })
   let resultPromise = Promise.allSettled([myPromiseOne,youPromiseTwo]);
   console.log(resultPromise);
   //Promise.all()一荣俱荣,一损俱损;
  let resultPromiseTwo = Promise.all([myPromiseOne,youPromiseTwo]);//报错

(三)String.protoType.matchAll()

javascript 复制代码
//String的matchAll方法,与正常的exec加上sg不同,该方法返回的是迭代器对象。
   let text2 = `<li>
               <a>天下无双</a>
               <p>2022/12/01</p>
                </li>
               <li>
               <a>冲天</a>
               <p>2003/11/23</p>
               </li>`;
   let zzM = /<li>.*?<a>(.*?)<\/a>.*?<p>(.*?)<\/p>/sg;
   let allResult = text2.matchAll(zzM);
   for(let m of allResult){
        console.log(m);
   }
   //下面执行next不能和上面循环共同出现,不然next在下面执行时指向空。
   console.log(allResult.next());
   console.log(allResult.next());

(四)可选链操作符

用来对传入对象类型的参数进行属性是否存在判断:

javascript 复制代码
//可选链操作符,用于对深层次对象类型参数进行属性判断
   function main(forEach){
    //原来判断,如果无错,会返回,如果有错直接报
    //let all = forEach && forEach.name && forEach.name.detailName && forEach.name.detailName.hiName;
    //使用可选链操作符,有错返回undefined
    let all = forEach?.name?.detailName?.hiName;
    console.log(all);
   }
   main({
        name:{
            detailName:{
                hiName: "大志"
            }
        },
        age: 18
   });

(五)大整型

javascript 复制代码
//大整数类型
 //1、声明
 let intMe = 193443n;
 console.log(intMe,typeof(intMe));
 //2、函数将变量转化为大整型
 let intHe = 18389384;
 let intRes = BigInt(intHe);
 console.log(intRes,typeof(intHe),typeof(intRes));
 //3、大整型计算
   //获取最大int数,正常情况下,这个数再加2就不会再往上加了;
 let bigInt = Number.MAX_SAFE_INTEGER;
 let nomalIntAll = bigInt + 2;
 let BigIntAll = BigInt(bigInt) + BigInt(2);//注意大整型不能和整型计算
 console.log(bigInt);
 console.log(nomalIntAll);
 console.log(BigIntAll);

(六)globalThis

globalThis始终执行windows对象,无论在任何位置,都可以使用它对windows对象进行操作。

(七)模块动态引入(import函数)

外部js模块:

javascript 复制代码
export function me(){
    alert("你好!");
}

动态引入:

javascript 复制代码
 //原方式,这种方式是在文件加载的时候直接引入
//  import * as hello from "./app.js";
//import函数会在事件发生时再引入模块
 let button = document.getElementById("myButton");
  button.addEventListener("click",()=>{
    import("./app.js").then(module =>{
        module.me();});});
相关推荐
程序员大阳14 分钟前
HTML+CSS+JS对话式实战(6)-学生端查看活动功能开发
javascript·css·html·模块·查看学生
jay神36 分钟前
基于 YOLOv8 的轴承缺陷检测(Web 版)
前端·人工智能·yolo
jay神44 分钟前
基于 YOLOv8 的森林火灾检测系统(Web 版)
前端·yolo
code2cat1 小时前
HTML基础篇之第一张网页:从index.html到浏览器里的任务清单
前端·html
miss2 小时前
AI 改完不敢上线?OpenSpec 规约驱动开发实战
前端·代码规范·前端工程化
AiMan2 小时前
腾讯ima还是不可以导出左侧所有对话,只能单条导出,方法不对吗
前端
去伪存真2 小时前
并发量一高就装死?Agent 全链路“防猝死”手册
前端·agent
Moment2 小时前
AI 编程时代,聊聊我的 Mac mini 双屏桌面
前端·后端
AiMan2 小时前
先确认能不能一次把Microsofat Copilot所有内容打包一个文件导出
前端
总要学点什么3 小时前
第97篇:三维数据加载-城市建筑白模自定义着色器——让一条光带沿高度扫上去,快慢却由帧率说了算
前端·gis·webgl·cesium·着色器·空间分析·白模