es5、es6、es7、知识点的归纳与总结(笔记)

in 网站建设
关注公众号【好便宜】( ID:haopianyi222 ),领红包啦~
阿里云,国内最大的云服务商,注册就送数千元优惠券:https://t.cn/AiQe5A0g
腾讯云,良心云,价格优惠: https://t.cn/AieHwwKl
搬瓦工,CN2 GIA 优质线路,搭梯子、海外建站推荐: https://t.cn/AieHwfX9

es5、es6

1.super

  1. super关键字使得子类调用了父类中的构造函数,父类可以使用子类传进来的属性进行各种运算,
  2. super 关键字 还可以调用父类的方法
  class Father{
    constructor(x,y){
         this.x=x;
         this.y=y;
     }
     
    sum(){
         console.log(this.x+this.y)  
       }
  
    say(){
         return "我是爸爸" 
      }
  }
 
  class Son extends Father{
    constructor(x,y){
       //调用了父类中的构造函数   
        super(x,y)
       //子类独有的属性
        this.x=x;
        this.y=y
      }
      
    say(){
       console.log(super.say())
    }
    
    //子类独有方法
    subtract(){
     console.log(this.x-this.y)
    }
  }
  
  let son=new Son(5,3);
  son.subtract();
  son.sum();
tips: 继承中的属性或者方法查找原则:就近原则

2.this指向

 var that //等于构造函数里this 即ldh这个对象
  class Star{
    constructor(name,age){
        that=this
        this.name=name
        this.age=age
        this.btn=document.querySelector('button');
        this.btn.onclick=this.sing
    }
  }
  
  sing(){
    /* 这个sing方法里的this,指向的是btn  这个按钮,因为这个按钮调用了这个函数 */
     console.log(this)
     console.log(this.name) //输出undenfind
     console.log(that.name) //输出ldh
   }
   
   dance(){ 
    /* 这个dance里面的this 指向的是实例对象 ldh 因为是ldh调用了这个函数 */
    console.log(this)
   }
   
   let ldh=  new Star(ldh,18)
   ldh.dance()

3.构造方法和原型(模拟面向对象)

   function Star(name,age){
      this.name=name;
      this.age=age;
      this.sing=funtion(){
         console.log(我会唱歌) 
      }
   }
   var ldh=new Star('刘德华',18);
   var zxy=new Star('张学友',19);
   /* new多个,基本属性不会,但sing方法会开辟多个不同的内存空间,存在内存浪费的现象 */。
   function Star(name,age){
      this.name=name;
      this.age=age;
      Star.prototype.sing=funtion(){
         console.log(我会唱歌) 
      }
   }
   
   Star.prototype ={
    /*如果我们修改了原来的原型对象,给原型对象赋值的是一个对象,则必须手动的利用constructor指回原来的构造函数*/ 
    constructor:Star
   }
   
   var ldh=new Star('刘德华',18);
   var zxy=new Star('张学友',19);
   ldh.sing()
   /* new多个,基本属性不会,但sing方法会开辟多个不同的内存空间,存在内存浪费的现象 */。

4.原型链

        function Star(name,age){
           this.name=name;
           this.age=age;
         }

        Star.prototype.sing=function(){
          console.log("我会唱歌");     
        }

        Star.prototype.sex='女' //构造函数原型成员 ,优先级中等
        Object.prototype.sex="男"//object对象的原型成员 ,优先级最低
        var ldh =new Star('刘德华',18)
        ldh.sex="男" //实例对象的原型成员 优先级最高
        console.log(ldh.sex)

        //打印这个实例向上找,可以找到Object
tips: 每个对象里都有 __proto__这个属性

5.利用原型对象,扩展内置对象方法

console.log(Array.prototype) 可以打印js的一些关于数组的api

 //在Array对象上添加自定义方法
Array.prototype.sum=function(){
   var sum=0;
   for(var i=0;i<thsi.length;i++){
       sum+=this[i];
   }
   return sum;
 }
 
var arr=[1,2,3]; 
console.log(arr.sum())
var arr =new Array(11,22,33)
arr.sum();

//不可采用以下方法加入方法
 Array.prototype=
 {
  sum: function(){
       var sum=0;
       for(var i=0;i<thsi.length;i++){
       sum+=this[i];
    }
      return sum;
   }
 }
tips: 自己加的原型方法会高亮,不可采用对象的方式去添加原型方法,会覆盖原先就存在的方法。

6.call 方法

   function fn(x,y){
     console.log('我想喝手磨咖啡');
     console.log(this);
     console.log(x,y);
   }
   
   var o={
      name:'andy'
   }
  
  fn.call() 
  
  /* 此时这个函数的this,就指向了o这个对象,指向哪个对象根据第一个参数决定*/
  fn.call(o,1,2)  
  1. 父构造函数
  function Father(name,age){
    //this 指向父构造函数的对象实例
     this.name=name;
     this.age=age;
  }
  
  2. 子构造函数
  //这个score用的son自己的属性
   function Son(name,age,score){
      //this 指向子构造函数的对象实例,
      //用call来调用Father这个构造函数,并把指向改成子类的构造函数的this,就实现了继承
      Father.call(this,name,age)
      this.score=score
    }
   var son=new Son('刘德华',18,200)
   console.log(son)

7. prototype 继承方法

原型对象(prototype)继承方法,通过原型链向上找规则,
Father实例(找不到向上找)->Father的原型对象的方法
就可以继承方法了,且子son方法定义自己的方法时不会影响到父

 //Father 是es5的构造函数
 son.prototype=new Father()
 son.prototype.constructor=son
 

8. 类的本质

类的本质其实还是一个函数 我们也可以简单的认为类就是构造函数的另外一种写法

9. 数组方法

     var
     arr=[12.66,4,88]
     var newArr=arr.filter((value,index,array)=>{
       return value>=2  //满足条件就把值放到新数组里
     })
tips:返回的是一个新数组,不会影响原来的数组
   var
   arr=[12.66,4,88]
   var flag=arr.some((value,index,array)=>{
     return value>=2  //满足条件就是true
   })
   
   arr=[12.66,4,88]
   var flag=arr.some((value,index,array)=>{
    if(value>30){
        return true  
    }
   })
   
tips:返回的是一个布尔值,如果查找到这个元素就返回true,不再进行循环,效率更高。

10. 字符串方法

trim 去除左右两边的空格,但不会去除中间的空格

str.trim()

11. object.defineProperty()

定义对象中新属性或修改原有的属性

object.defineProperty(obj,prop,descriptor)

object.defineProperty的参数

参数 是否必需 类型 说明
obj true Object 目标对象
prop true String 需新定义或修改的属性的名字
descriptor true Object 目标属性所拥有的的特性
 var obj={
     id:1,
     pname:"小米",
     price:1999
 }
 
 //对对象定义新属性并赋值,以前的写法
 obj.num=1000;
 obj.price=99;
 //现在的写法
 
 Object.defineProperty(obj,'num',{      
 })

第三个参数descriptor的参数

参数 是否必需 类型 说明
value false mixed 设置属性的值 默认undefined
writable false boolean 是否可以重写 默认false
ebumerable false boolean 目标是否可以被枚举(遍历),默认false
configurable false boolean 目标属性是否可以被删除或是否可以再次修改特性true/false 默认为false
tips: 注意新定义的descriptor 都是默认为false 用obj={} 来定义的因为没有定义是否可以被XX操作所以都是true

12.函数

所有的函数都是Function的实例(对象),函数也是个对象,万物皆对象

一、 函数的定义方式
1.自定义函数(命名函数)

function fn(){};

2.函数表达式(匿名函数)

var fun =function(){
    
}

3.利用new Function (不推荐,效率低)

new Function('参数1','参数2','函数体')
参数 是否必需 类型 说明
参数1 false String 第一个参数
参数2 false String 第二个参数
函数体 false String 第三个参数
tips:如果只有一个参数那么就是函数体

二 、 函数的调用方式
1.普通函数

this 指向window

function fn(){
   console.log('人生的巅峰') 
}

fn() (window.fn())
fn.call()

2.对象的方法

this指向o

 var o ={
   sayHi:function(){
         console.log('人生的巅峰')  
   }  
 }
 
 o.sayHi();

3.构造函数

this 指向实例对象

function Star(){};

new Star();

4.绑定事件函数

this 指向是函数的调用者btn这个按钮对象

//点击了按钮就可以调用这个函数
btn.onclick=function(){};

5.定时器函数

this指向的是window

这个函数式定时器自动1秒钟调用一次

setInterval(function(){     
},1000);

6.立即执行函数

this 指向window

(function(){
  console.log('人生的巅峰') 
})()
tips: 立即执行函数是自动调用
调用方式 this指向
普通函数调用 window
构造函数调用 实例对象,原型对象里面的方法也指向实例对象
对象方法调用 该方法所属对象
事件绑定方法 事件绑定对
定时器函数 window
立即执行函数 window

13.改变this指向

     var o={
        name:"1"
     }
     functon fn(a,b){
         console.log(a+b)
     } 
     fn.call(o,1,2) 
tips: 后两个参数是形参 用于参与fn的一些对象,主要用于在es5中实现继承
       var o={
        name:"1"
     }

     functon fn(a,b){
         console.log(a+b)
     }

    fn.apply(o,[1,2]) 
    var arr=[1,66,4]
    //如果不想改变this(指定对象)就写个null,但不合适写Math就行了
    Math.max.apply(Math,arr)
tips:参数必须是数组,但打印后却是字符串或是数字(根据数组里的数据类型,判定)
    var o={
       name:"1"
     }
     functon fn(a,b){
         console.log(a+b)
     }
     var f= fn.bind(o);
     f();
     //亦或者是
      functon fn(a,b){
         console.log(a+b)
      }.bind(this)

14. call、apply、bind总结

15. 严格模式

    //为整个脚本开启严格模式

         <script>
         'use strict';
          </script>

          <script> 
          (function()){
            'use strict';
          }() 
          </script> 

          //为某个函数开启严格模式

          <script> 
             function fn(){
                'use strict';
                 /*里面的代码按照严格模式执行*/
              }

              function fun(){
                 /*里面的还是按照普通模式执行*/
               }

          </script>
tips:兼容ie10以上,ie10以下会忽略这个模式

16. 高阶函数

高阶函数- 函数可以作为参数传递,参数的接收方就是高阶函数,即 fn

 function fn (a,b,callback){
     console.log(a+b);
     callback && callback()
  }

 fn(1,2,function(){
    console.log(我是最后调用的);
 })
 

17. 闭包

 function fn (){
     var num=10;
     function fun(){
      console.log(num)
     }
     fun ()
 }

fn

function fn(){
    var num=10;
    return function(){
     console.log(num)   
    }
}

//这里f保存的是个函数
var f=fn()
//这里输出的是num
f()
for (var i=0;i<lis.length;i++){
/*利用for循环创建了4个立即函数*/
/*立即执行函数也成为小闭包因为立即执行函数里面的任何一个函数,都可以使用它的i这个变量*/


/*这里的i是从底下的那个i传进来的*/
(function(i){

lis[i].onclick=function()  {
    console.log(i)
 }
})(i) 
tips:闭包的主要作用:延伸变量的作用范围。但闭包容易照成内存泄漏,它一直不释放资源,闭包总结:闭包是一个函数,闭包延伸了作用域范围

18. 递归

    function fn(n){
      if(n==1) return 1;
       return n*fn(n-1);
    }

    console.log(fn(3))
    执行过程

    return 3*fn(2)
    return 3*(2*fn(1))
    return 3*(2*1)
    return 6
    function fb(n){
      if(n===1 || n===2){
          return 1
      }
      return fn(n-1)+fb(n+2);
    }

    console.log(fb(3))
    console.log(fb(3))
     var data=[
     {
       id :1,
       name:'家电'
       goods':[
        {
           id :11,
           name:'家电11'
        },
         {
           id :12,
           name:'家电12'
        }
       ]
     }
      {
       id :2,
       name:'家电2'
       goods':[
        {
           id :13,
           name:'家电13'
        }
       ]
     }
    ]

    function getID(json,id){
     var o ={};
     json.forEach(function(item)) {
      if(item.id==id){
         console.log(item);
         o=item;    
      }else if(item.goods&&item.goods.learth>0){
         o= getID(item.goods,id)
       }
      }
     } 
     console.log(getID(data,1))

tips: 开辟内存空间,容易照成死递归,出现栈溢出。在forEach里面执行递归,不加退出条件,循环已经帮你加了。

19. 浅拷贝和深拷贝

    var obj={
     id:1,
     name:"andy", 
     msg:{  //这个对象是深层次对象会被浅拷贝,会被拷贝地址,修改o同时会修改obj,这个就是浅拷贝
         age:18
     }
    }
    
     var o={}
     for(var k in obj){
      //k 是属性名
      // obj[k] 属性名
       o[k]=obj[k];
     }
     console.log(o);
     o.msg.age=20;
     console.log(obj)

2.es6的语法糖实现浅拷贝

  Object.assign(o)
  /*主要用来对,对象赋值, key值相同的会覆盖
  其他没进行赋值的不会处理,因为是浅拷贝所以会影响原数组
  */
    function deepCopy(newobj,oldobj){
     for(var k in oldobj){
      var item=oldobj[k];
      if(item instanceof Array){
        newobj[k]=[];
       //判断是否是数组
        deepCopy(newobj[k],item)
      }else if(item instanceof Object){
        //判断是否是对象
         newobj[k]={};
         deepCopy(newobj[k],item)
      }else{
       // 简单数据类型
        newobj[k]=item;
       }
      }
    }
2.用JSON.stringify()和 jSON.parse() 来实现 深拷贝
tips: 数组也属于Object 所以要把Array判断写在object的前面。

总结:浅拷贝,深层次的数据如数组和对象只会拷贝引用,修改拷贝后的数据会同时修改原来的被拷贝的的数据,深拷贝,是对数组和对象开辟不同的空间,被拷贝的的数据。

20. 正则表达式

   灵活性、逻辑性和功能性非常的强,
可以迅速地用极简单的方式达到字符串的复杂控制

    var regexp=new RegExp(/123/)
    console.log(regexp) 

2.利用字面量,创建正则表达式,即用//即注释的中间写上规则匹配就是正则表达式了

     var rg=/123/;
     /*
      可用test 方法来检测是否符合正则表 返回true或false
     */
     var rg=/123/;
     console.log(rg.test(123));
    var rg=/^abc/ ^匹配的是开头,这里的是abc
    var rg=/^abc$/ 精确匹配 只有输入abc 才会匹配
      /* 只要包含a,或者b,或c,其中一个就可以了 */
     var rg=/[abc]/

    /* 只能选择一个a或者b或者c其中的一个 三选一 */
       var rg=/^[abc]$/

    /* 只能选择一个a-z,26字符中其中的一个字符,26选一
    表示到a到z的范围 可以在[]中添加各种字符组合
    */  
      var rg=/^[a-zA-z]$/

    /* 如果中括号里 ^ 表示取反的意思 不要和边界符 ^ 混淆 取反即      以下就不能是 a-z和A-z 
    */ 
      var rg=/^[^a-zA-z]$/
     //* 相当于>=0 可以出现0次或者很多次

    var rg=/^a*$/;
    console.log(rg.test('')) 
    console.log(rg.test('aaa'))

    //+ 相当于>=1 可以出现1次或者很多次,不能不出现,即0次
      var rg=/^a+$/;
     console.log(rg.test('')) 
    console.log(rg.test('aaa'))

    //? 相当于 1 || 0  可以出现1次或者0次 
     var rg=/^a?$/;
     console.log(rg.test('')) 
     console.log(rg.test('a')) 
     console.log(rg.test('aaa')) 

    //{3}就是重复出现3次

    var rg=/^a{3}$/;
    console.log(rg.test('')) 
    console.log(rg.test('aa')) 

    console.log(rg.test('aaa')) 

    //{3,}出现大于等于3

    console.log(rg.test('')) 

    console.log(rg.test('aaa'))

    //{3,16}出现大于等于3并且小于等于16

    var rg=/^a{3,16}$/;

    console.log(rg.test(''))

    console.log(rg.test('a'))
    模式是 :[a-zA-z] 某个规则
    量词符:{6,16} 这个规则的里字符可出现的次数 即只能出现6-16个a-zA-z 里的字符 且全部合起来只能有6-16个。
    var rg=/^[a-zA-z]{6,16}$/
    //这里有小括号所以表示 abc 重复3次
    var rg=/^(abc){3}/
    //这里没有小括号 c 重复3次
    var rg=/^abc{3}/
预定类 说明
d 匹配0-9之间的任一数字,相当于[0-9]
D 匹配0-9以外的字符,相当于1
w 匹配任意的字母、数字、和下划线,相当于[A-Za-z0-9_]
W 匹配任意的字母、数字和下划线以外的字符,相当于2
s 匹配空格(包括换行符、制表符、空格符等),相当于[trnvf]
S 匹配非空格(相当于3
//座机号码验证 010-12345678 0591-1234567

 //第一种
 var reg=/^\d{3}-\d{8}|\d{4}-\d{7}$/
 //第二种
 var reg=/^\d{3,4}-\d{7,8}$/
 
 //手机号码的正则表达式
 var rg=/^1[3|4|5|7|8]\d{9}$/;
//qq号的正则 10000开始
var rg=/^[1-9]\d{4,}$/ 
var str=str.replace(/andy/,bady)
参数 说明
第一个参数 被替换的字符串或者正则表达式
第二个参数 替换为的字符串

返回值 是一个替换完毕的新字符串

tips: 正则表达式里面不需要加引号, 不管是数字型还是字符串型,正则表达式的中间不要有空格即//里添加的内容不要用空格来间隔

以下都是es6、es7的知识点

1.let关键字

     if(true){
         let a=1;
         var b=3
     }

     console.log(a) //访问不到 undefined
     console.log(b) //访问的到,输出3
      var num =10
      if(true){
        console.log(num)  undefined
        let num=1
      }

     /* num输出在块级作用域里,使用的是块级的作用域定义的变量,而且是在未定义前输出所以是undefined */
      for (var i=0;i<10;i++){
           console.log(i)
           setTimeOut(function(){
              console.log(`i:${i}`)
        })
      }
      在var定义的变量下,定时器里输出的都是10 
      因为此时循环已经结束了,i是最后的一个值。

      用let 可以正常循环输出

2.const关键字

      const a =1
       a=3 //报错,值不能更改
      const arr=[1,2]
      arr[0]=3  //可更改,只是更改结构内部的值   arr=[3,2]
      arr=[34,44] //不可更改整体都更改,是地址的更改,不允许
tips: 如果让对象里的属性不可进行修改可以使用es5的方法 Object.freeze(arr) 此时 arr内部的属性也不能更改

3.解构赋值

    let [a,b,c]=[1,2,3] || [];
    console.log(a,b,c,d,e)
    a 、b、c 输出 1,2,3 d,e是undefined
    let person ={name:'zhangsan',age:20}
    let {name,age}=person || {}
    console.log(name) //zhangsan
    console.log(age) // 20
    let {name:myName,ages:myAge}=person
    console.log(myName,myAge) //也可以输出
    //第一种情况,把整个的对象赋值给另一个读写
    let user = { a: 1,b: 2,c: 3,d: 4,e: 5}
    let 
    {
      aa = { a: user.a, b: user.b }, 
      bb = { ...user } 
    } = {}

    /*
    第二种情况,可以把对象的值分配到不同的对象
    */
    let users = {}, userDetails = {};
    ({ a: users.a, b: users.b, ...userDetails } = user);
    console.log(users, userDetails)

    //users {a:1,b:2}  userDetails {c:3,d:4,e:5}
     const Tom={

         name: 'Tom jones',
         age:25,
         family:{
             mother: 'Norah Jones',
             father: 'Richard Jones',
             brother: 'Howard Jones'
         }
     }

     //只有在变量是underfine时,才能使用默认值 null false 0 都是有值的
     const { father:f,mother:m,brother='sss' } = Tom.family || {} ;

    //以上的f、m 是别名 输出用别名
  let a=10
  let b=20
  [a,b]=[b,a]

  console.log(a,b) //a输出 20 b输出10
tips: 第二种情况,一定要加上括号。

4.箭头函数

    function sum(num1,num2){
        return num1+num2
    }

    const sum=(n1,n2)=>{
      return n1+n2    
    }

    //以上代码只有一行,且return这行代码就可以简写为
    const sum=(n1,n2) => n1+n2
      var num=10
      let obj={
          num:1
          say:(){
              console.log(this.num)
          }
      }
     obj.say() //这里输出的是10
     const gg=()=>{
        console.log(1)
     }
      1.作为构造函数,一个方法需要绑定到对象 
       const Person=function(name,points){
           this.name=name
           this.points=points;
       }
       const jelly=new Person('jelly',5);

      2.原型添加方法
       Person.prototype.updatePoints=function(){
           this.points++
           console.log(this.points)
       }

      3.事件
       const  button=document.querySelector('.zoom');
       button.addEventListener('click',function(){

       })

      4.需要使用arguments

      const sum =function(arguments){
        /*arguments不是个真正的数组 需要用Array.from 转换 或用扩展运算符[...arguments]来转换*/   
       return Array.from(arguments).reduce((prevSum,value)=>pervSum+value,0 )

       }
tips: 对象是不产生作用域,指向的s是全局window,所以箭头函数的this,指向的是window,所以这里输出的是10

5.剩余参数

    //定义个方法
    const sum =(...args)=>{
         let total=0;
         args.forEach(item=>{
            total+=itme 
         })
         return total
    }
    sum(10,20) //args里保存着10和20
    sum(10,20,30)//args里保存10,20,30
    let ary1=['张三','李四','王五']
    let [s1,...s2]=ary1
    s1 //存着张三
    s2 //接收剩余参数成为个新数组,存着李四和王五

6.扩展运算符

    let ary=[1,2,3];
    ...ary //1,2,3 转为去掉括号的用逗号分隔的参数序列
    console.log(...ary) 1 2 3
    let ary1=[1,2,3]
    let ary2=[4,5,6]
    ...ary1  //1,2,4 
    ...ary2  //4,5,6
    //第一种
    let ary3=[...ary1,...ary2]
    //第二种  -- push方法可以有多个参数
    ary3=ary1.push(...ary2)
    var Odivs=document.getElementsByTagName('div')
    console.log(Odivs) //伪数组 可迭代遍历但没有数组方法
    var ary=[...Odivs]
    ary.push('a')
    console.log(ary);
    1. //把二维数组扩展成对象数组
     [...array[1],...Array[1]] 
     输出
     [object,object]

    2. //可用来代替apply方法
     const fruit=['apple','bananas','pear'] 
     const newFruit=['orange','mongo']

     //用apply合并数组,apply后面跟着的参数是数组
     fruit.push.apply(fruit,newFruit) 
     //用扩展运算符来合并
     fruit.push(...newFruit) 

7 array.from() --数组的扩展方法

例子1
var arrayLike={
    "0":"1",
    "1":"2",
    "length":2 
}
Array.from(arrayLike,item=>item*2)

例子2 
const todos=document.querySelectorAll('li');
const names=Array.from(todos,todo=>todo.textContent);
console.log(names)
 const str='abc'
 console.log(Array.from(str))  [a,b,c]

8 array.find() --数组的扩展方法

let ary=[{
    id:1,
    name:'张三'
 },{
    id:2,
    name:'李四'
 }
]

let target= ary.find(item=> item.id==2 )

9 array.findIndex() --数组的扩展方法

let ary=[10,20,50]
const index= ary.findIndex((item,index)=>itme>15)
console.log(index)

10 array.includes() --数组的扩展方法

 let ary=["a","b",c]
 ary.includes("a")

11 array.of() --数组的扩展方法

当前方法可以弥补 new Array 构造方法返回结果不一致问题。

/*当参数只有一位的时候,返回的是长度为1的数组 [undefined*1],而不是[1] 只有当参数是多个的情况下才会返回正确的数据*/
new Array(1)
array.of(1)  输出的是[1]

12 array.every() --数组的扩展方法

当遍历时遇到false时,就不执行了,返回false

13 模板字符串 --String的扩展方法

let name=`账上`
let sayHello =`hello${name}`
let result={
    name:"Zhangsan",
    age:20
}

let html=`
 <div>
   <span>${result.name}</span>
    <span>${result.age}</span>
</div>
`
  const fn=(){
    return '我是fn函数'
  }
  
 let html=`我是模板字符${fn()}`
 
  const template=`
  <div class="greet">
    <p> Hello </p>
  </div>
  `.trim()
  
  //模板字符串本身就是字符串,所以可以使用字符串方法
 
  function renderTodos(todos){
      return (
        `<ul>
            ${todos.map(todo=>`
              <li>
                 ${todo.name} ${todo.completed?'√':'X'}
              </li>`).join('')}
       </ul> `
      )
   }

 //map 返回的是数组 循环渲染有,所以用join 去除
const user='Mary';
const topic='learn to use markdown'
//模板字符串加方法
function highLight(strings,...values){
 //strings 输出的是:has commented on your topic
 //values 输出的是:user和topic
}
const sentence= hightlight `${user} has commented on your topic ${topic} `

14 startsWith()、endsWith()

--String的扩展方法

let str='hello world';
str.startsWith('Hello') //true
str.endsWith('!') 、//true

//可传递第二个参数, 从第几个参数开始  
str.startsWith('Hello',6)

15.repeat --String的扩展方法

'x'.repeat(3) // "xxx"
'hello'.repeat(2) //hellohello
 const id  ='510300198007300366x'
 const fan ='I love Laravist.'
 function padder(string,length=25){
    return `${'',repeat(Math.max(length-string.length,0))}${string}`
 }

 console.log(padder(id))
 console.log(padder(fan))

16. for or循环遍历

支持数组、字符串等 但目前版本不支取对象的循环

Array.protype.frist=function() {
    return this[0]
}
const fruits=['Apple','Bannana','Orange','Mango'];
fruits.describe='My favorite fruits';

for(let index in fruits ){
   console.log(fruits[index] ) 会输出多余的值 
 }

for(let index of  fruits ){
   console.log(index ) 只输出数组内的值 可以 break
 }

//迭代器
for(let [index,fruit] of fruits.entries() ){
   console.log(index,fruit ) 只输出数组内的值 可以 break
 }

17.set 数据结构

const s=new Set()
s.size //看s的长度
const s3=new Set(["a","b","b"])
//用扩展运算符,变成用逗号分隔的
const arr=[...s3]
tips: set的方法可以使用链式调用
 const s5=new Set(['a','b','c'])
 s5.forEach(value=>{
     console.log(value)
 })

18. 递归

//接口返回数据结构--是个数组

0: {menu_id: 92, menu_name: "微信公众号", menu_fid: 0, menu_val: "92_wechat_publicnumber"}
1: {menu_id: 1, menu_name: "学校管理", menu_fid: 0, menu_val: "1_school"}
2: {menu_id: 2, menu_name: "教师管理", menu_fid: 0, menu_val: "2_psychologist"}
3: {menu_id: 3, menu_name: "学生管理", menu_fid: 0, menu_val: "3_counseling"}
4: {menu_id: 4, menu_name: "量表中心", menu_fid: 0, menu_val: "4_scale"}
5: {menu_id: 5, menu_name: "心理咨询", menu_fid: 0, menu_val: "5_advisory"}
6: {menu_id: 6, menu_name: "异常反馈", menu_fid: 0, menu_val: "6_abnormal"}
7: {menu_id: 7, menu_name: "活动管理", menu_fid: 0, menu_val: "7_activity"}
8: {menu_id: 8, menu_name: "在线求助", menu_fid: 0, menu_val: "8_help"}
9: {menu_id: 9, menu_name: "心理课堂", menu_fid: 0, menu_val: "9_classroom"}
10: {menu_id: 10, menu_name: "心理实验", menu_fid: 0, menu_val: "10_experiment"}
11: {menu_id: 11, menu_name: "订单管理", menu_fid: 0, menu_val: "11_order"}
12: {menu_id: 12, menu_name: "数据分析", menu_fid: 0, menu_val: "12_data"}
13: {menu_id: 14, menu_name: "学校列表", menu_fid: 1, menu_val: "14_school_list"}
14: {menu_id: 15, menu_name: "学校资讯", menu_fid: 1, menu_val: "15_information_list"}
15: {menu_id: 17, menu_name: "学校横幅", menu_fid: 1, menu_val: "17_schoolad_list"}
16: {menu_id: 18, menu_name: "老师列表", menu_fid: 2, menu_val: "18_psychologist_list"}
17: {menu_id: 19, menu_name: "老师导入", menu_fid: 2, menu_val: "19_teacher_import"}
18: {menu_id: 20, menu_name: "发送信息", menu_fid: 2, menu_val: "20_edit_notice"}
19: {menu_id: 21, menu_name: "学生列表", menu_fid: 3, menu_val: "21_counseling_list"}
20: {menu_id: 22, menu_name: "学生导入", menu_fid: 3, menu_val: "22_counseling_import"}
21: {menu_id: 23, menu_name: "发送信息", menu_fid: 3, menu_val: "23_edit_cou_notice"}
22: {menu_id: 24, menu_name: "用户统计", menu_fid: 3, menu_val: "24_user_count"}
23: {menu_id: 25, menu_name: "综合档案", menu_fid: 3, menu_val: "25_comprehensive_file"}
24: {menu_id: 26, menu_name: "量表分类", menu_fid: 4, menu_val: "26_scale_shape"}
25: {menu_id: 28, menu_name: "量表权限", menu_fid: 4, menu_val: "28_scale_rights"}
26: {menu_id: 29, menu_name: "测评查询", menu_fid: 4, menu_val: "29_assess_search"}


//根据fid生成带孩子的二级树形结构--只有二级就简单点

getJsonTree (data, fId) {
      let itemArr = [];
      data.forEach(item => {
        const { menu_id = 0, menu_fid = 0, menu_name = '', menu_val = '' } = item || {}
        if (menu_fid === fId) {
          let newNode = {
            id: menu_id,
            label: menu_name,
            value: menu_val,
            checkAll: false,
            checkedOptions: [],
            options: this.getJsonTree(data, menu_id) //第一个是0写死的id找不到父亲的,找到的都是当父亲的,第二个就是把自己的id当做是fid 去找它的孩子
          };
          itemArr.push(newNode);
        }
      })
      return itemArr;
    },

// 孩子的数组,特殊情况就用这个来代替 this.getJsonTree函数 (只限于二级)

    getChild (data, fId) {
      let itemArr = [];
      data.forEach(item => {
        const { menu_id = 0, menu_fid = 0, menu_name = '', menu_val = '' } = item || {}
        if (menu_fid === fId) {
          let newNode = {
            label: menu_name,
            value: menu_val,
          };
          itemArr.push(newNode);
        }
      })
      return itemArr;
    },
    

19. 对象字变量的扩展

es6 对象 变的更加强大

 const name='Lara'
 const age=2

 const keys=['name','age']
 const values=['lara',2]
 
 const laravist={
  [keys.shift()]:values.shift(),
  [keys.shift()]:values.shift(),
  [keys.shift()]:values.shift(),
 }

20. promise

 const p=new Promise(reslove,reject)=>{
   setTimeout()=>{
     reject(Error('Error'))  
   }  
 })

 p.then(data=>{console.log(data)})
  .catch(err=>{console.log(err)})
  
tips: 在reject中使用Error返回错误信息时,使浏览器正确定位到是reject那行发出的错误信息,而不是catch那行。
const userPromise=new Promise((resolove,reject)=>{
  setTimeout(()=>{
      reslove(['mojom','vanpe'])
  },2000)    
})

const moviePromise=new Promise(()=>{
  setTimeout(()=>{
      reslove({name:"摔跤",rat:9.2})
  },500) 
})


 Promise.
  all([userPromise,moviePromise])
 .then(responses=>{
   console.log(responses)
 })
 .catch(responses=>{
  console.log(responses)
 })
tips: Promise all 当以上所有promise都正确执行时,才返回正确的,否则会被catch捕获。

当第一个调用的promise 正确执行时就在then中返回结果,不然就在catch中返回

21. Symbol

 const peter=Symbol('peter');
 const student=Symbol('student');
 //以下nina两个key值重复,所以用Symbol来标识
 const classRoom={
   [Symbol('lily')]:{grade:60,gender:'female'},
   [Symbol('nina')]:{grade:60,gender:'female'},
   [Symbol('nina')]:{grade:60,gender:'female'},
 }
 
//for 循环不能遍历
 for(let key of classRoom){
     console.log(key) //输出[]
 }

//另类遍历的方法
 const syms=Object.getOwnPropertySymbols(classRoom).map(sym>classRoom[sym])
 console.log(syms)

tips:classRoom[sym] 不能改成 classRoom.sym 这里会执行 classRoom['sym']但classRoom数据里并没有sym这个属性名

22. eslint 代码规范

 /* globals Vue */
 
 .eslintrc.js 文件中
  globals: {
    Yx: true
  }

 
 /* eslint-disable no-new */
 /* eslint-enable no-new */
 {
     "plugins":["markdown"]
 }

23 Reflect.ownKeys()

静态方法 Reflect.ownKeys() 返回一个由目标对象自身的属性键组成的数组。

const object1 = {
  property1: 42,
  property2: 13
};

var array1 = [];
console.log(Reflect.ownKeys(object1));
// expected output: Array ["property1", "property2"]

console.log(Reflect.ownKeys(array1));
// expected output: Array ["length"]

24. parseInt

转化为整形

 //可以使用+也可隐士转化为数字
 +'243'

25. class

 let methodName = 'info'
  class User {
    constructor(name,age){
        this.name=name;
        this.age=age;
    }
    
    [methodName](){
         console.log(1)
      }
  }
  class student extends User {
    constructor(name,age){
        super(name);   
      /*super的作用及原理
       作用 :继承父类,等同于User.call(this,name)调用基类的构造函数
       原理:  student.prototype=new User()
       类的原型被改变了,但是类的原型的构造函数的也改变了,要指定构造函数为student
        student.prototype.constructor =student
      */
       this.age=age;
    }
  }

为Array 添加自己的方法

class Movie extends Array {
  constructor(name,...items){
     super(...item)
     this.name=name
    }
    
   add(movie){
   //
    this.push(movie)
  }    
}

const movies=new Movie('favorite movies',
{name:'rr1',score:8.7},
{name:'rr2',score:99.7},
{name:'rr3',score:91.7}
)

movies.add() //添加内容

26. Iterator

遍历器(迭代器)

const colors=[1,2,3]
const iterator= colors[Symbol.iterator]()
iterator.next()

/*输出*/
Object{value:1,done:false }
iterator.next()

/*输出*/
Object{value:2,done:false }
iterator.next()

/*输出*/
Object{value:3,done:false }
iterator.next()

/*输出*/
Object{value:undefined,done:true}
tips:
当done为true时遍历就结束了,输出一个方法时有包含Iterator,就是遍历器了,比如数组的 keys,entries,
values
//实现一个Array.values
Array.prototype.values=function(){
 let i = 0;
 let items = this;
 return{
  //返回一个函数,形成闭包,可以进行累加
  next(){
    const done =i > = items.length;
    const value = done?undefined:items[i++]
    return{
        value,
        done
     }   
   }   
  }
}

for of 的运行机制

for(const itme of color){}
//of调用,colors[Symbol.iterator]() 这个属性。 并把里面的value值赋值给color

27. generator (可不学,直接看async、await)

function* listColors(){
   let i=0;
    yield i; //返回
   i++;
    yield i;
   i++;
    yield i;
 }

//生成了遍历器
const colors=listColors();

colors.next()
/*输出*/
Object{value:0,done:false}

colors.next()
/*输出*/
Object{value:1,done:false}

colors.next()
/*输出*/
Object{value:2,done:false}

colors.next()
/*输出*/
Object{value:undefined,done:true}

const colors=[1,2,3]
function* loop(repos){
 console.log(colors)
 for(const repo of repos){
    yield repo
 }
}
const repoGen=loop(repos)
//进行ajax方法
 function ajax(url){
   axios.get(url).then( res => 
   执行成功后再执行下一步
   userGen.next(res.data)
  )     
}
//生成器 
function* steps(){
  const users = yield ajax('https://api.github.com/users');
  const firstUser = yield ajax(`https://api.github.com/users/${users[0].login}`)
  const followers = yield ajax(firstUser.followers_url);
}
const userGen =steps()
userGen.next()

28.proxy

 const person = {name:'laravist',age:2000};
 const personHandle={
   //获取值
   get(target,key){
     //target:原目标; key:键值
     //把属性值都转换成大写
      return target[key].toUpperCase(); 
    }
   //设置值
   set(target,key,value){
     //去掉空格
     if(typeof value==='string'){
       target[key]=value.trim()
     }
    }
 }
 const personProxy = new Proxy(person,personHandle)
 personProxy.name=' codecasts '
 console.log(personProxy.name)
 // 输出:CODECASTS  --去去掉空格并转换成大写
// 安全挟持
const safeHandler = {
  set(target,key,value){
      //找相类似的键
      const likekey = Object.keys(target).find(k=>k.toLowerCase()===key.toLowerCase());
      //如果找到就不让其赋值
      if(!(key in target) && likekey ){
        throw new Error(` Oops! looks like we already have a property ${key} but with the case of ${likeKey}`)    
       }
   }  
}

const safetyProxy=new Proxy({id:2}, safeHandler); 
safetyProxy.ID=5  /*会报错,赋值已经被挟持了只要和id这个键值相类似的 比如 Id ID iD 都不让赋值*/ 

29.set

 // 定义一个set
 const colors=new Set()
 colors.add(4)//添加元素
 colors.delete(4)//删除
 colors.has(4)//检验是否存在

 /*可以用正常的数组循环方式进行循环*/
 for(let color of colors ){
   console.log(color)
 }
 
 colors.forEach(item=>{
     console.log(item)
 })
 
 const colorsSet=new Set([1,2,3,4,4,4,4])
 const colorsArr=[...colorsSet]
 // 或者可以通过array.from() 来进行转换

30.WeakSet

const {
  jelly:{name:'jelly',age:20},
  mary:{name:'mary',age:25}
} ={}

const weakPeople=new WeakSet([jelly,mary])
console.log(weakPeople)
mary=null
console.log(weakPeople) 

// mary 这个属性值就不见了, 如果用数组来存储,这个值还是存在的

31.map

 const people = new map();
 people.set('jelly',23)
 people.has('jelly')    //检验是否含有jelly这个值
 people.delect('jelly') //进行删除
 people.clear()全部删除
 //对 fruits 进行赋值 
 const fruits = new Map([['apple',6],['banana',5]])
 
 //用forEach和解构的方式来遍历map
 fruits.forEach([key,value]=>{
  console.log(key,value)   
 })
 //如果不用解构方式,他返回的值是一整个是数组

32.weakMap

 const jelly = {name:'jelly'};
 const miffy = {name:'miffy'}

 const strong= new Map();
 const weak=new WeakMap();
 
 strong.set(jelly,'jelly is the best!')
 weak.set(miffy,'miffy is the 2nd best!')
未完待续


  1. 0-9
  2. A-Za-z0-9_
  3. trnvf
关注公众号【好便宜】( ID:haopianyi222 ),领红包啦~
阿里云,国内最大的云服务商,注册就送数千元优惠券:https://t.cn/AiQe5A0g
腾讯云,良心云,价格优惠: https://t.cn/AieHwwKl
搬瓦工,CN2 GIA 优质线路,搭梯子、海外建站推荐: https://t.cn/AieHwfX9
扫一扫关注公众号添加购物返利助手,领红包
Comments are closed.

推荐使用阿里云服务器

超多优惠券

服务器最低一折,一年不到100!

朕已阅去看看