• ES6高级技巧(四)


    238

    数字->二进制->补码->十进制

    const bitwise = N => {
        if (N < 2) {
            return N == 0 ? 1 : 0
        }
        /*转化为二进制*/
        let str = N.toString(2)
        /*补码*/
        let sb = ''
        for (let i = 0; i < str.length; i++) {
            sb += str.charAt(i) == '0' ? '1' : '0'
        }
        /*转化十进制*/
        return parseInt(+sb, 2)
    }
    console.log(bitwise(10))
    

    some

    some的实现逻辑本身就是短路的,一旦返回true后续迭代就不再执行了

    let arr = [1, 2, 3, 4, 5]
    let sum = ''
    arr.some(v=>{
      sum+=v
      if (v == 3) {
        return true
      }
    })
    console.log(sum)
    

    如果continue和break同时存在

    let arr = [1, 2, 3, 4, 5]
    let text = ''
    for (let v of arr) {
      if (v === 2) {
        continue
      }
      if (v === 4) { 
        break
      }
      text += v + ','
    }
    console.log(text) // "1,3,"
    

    只用some处理

    arr.some(val => {
      if (val == 2) {
        return     //跳过
      }
      if (val == 4) {
        return true
      }
      sum += val
    })
    console.log(sum)
    

    判断undefined

    const isUndefined = value => value == void 0
    let a;
    console.log(isUndefined(a)) //true
    

    合并对象

    const isObject = value => toString(value) === '[object Object]'
    
    const merage = (a, b) => {
      for (let item in b) {
        if (isObject(b[item])) {
          a[item]=merage(a[item],b[item])
        }else{
          a[item]=b[item]
        }
      }
      return a
    }
    

    去重value

    const uniqueBy = (arr, fn) => {
      return arr.filter((val, index, array) => {
        return array.findIndex(item =>
            typeof (fn) == 'function' ? fn.call(this, item) == fn.call(this, val)
              : val[fn] == item[fn])
          == index
      })
    }
    

    递归逆序

    const fun = num => {
      let num1=num/10
      let num2=num%10
      if (!Math.floor(num1)) {
        return num
      }
      if (Math.floor(num1)) {
        return `${num2}`+fun(Math.floor(num1))
      }
    }
    console.log(fun('12345'))
    //不用递归,不用api
    const fun = num => {
      let end=num.length-1
      let sum=''
      while (end>=0) {
        sum+=num[end]
        end--
      }
      return sum
    }
    console.log(fun('12345'))
    

    深度克隆

    const isObject=obj=>Object.prototype.toString.call(obj) === '[object Object]'
    const deepClone = (obj) => {
      //基础数据类型是值传递
      let arr = ['string', 'number', 'boolean', 'undefined']
      if (arr.some(val => typeof obj == val)) {
        return obj
      }
      //数组
      let cobj;
      if (Array.isArray(obj)) {
        cobj = obj.map(val => deepClone(val))
      }else{
        if (isObject(obj)) {
          let ret={};
          for (let item in obj) {
              ret[item]=deepClone(obj[item])
          }
          return ret
        }
      }
      return cobj
    }
    console.log(deepClone({a:1,b:{a:1},c:3}))
    

    禁止右键,选择,复制

    // 鼠标右键事件   选择             复制
    ['contextmenu', 'selectstart', 'copy'].forEach(function (ev) {
        document.addEventListener(ev, function (event) {
            return event.preventDefault()
        })
    })
    //event.preventDefault()  阻止默认的点击事件执行
    

    判断是不是引用数据类型的数据

    function isObject(value) {
      	let type = typeof value;
      	return value != null && (type == 'object' || type == 'function');
    }
    

    数据结构和算法是什么

    数据结构是值一组数据的存储结构

    算法就是操作数据的方法

    数据结构和算法是相辅相成的,数据结构是为服务的,而算法要作用在特定的数据结构上

    递归

    //阶乘
    const fact = n => {
        if (n == 1) {
            return n
        }
        return fact(n - 1) * n
    }
     console.log(fact(5))
    
    //最大公约数
    const gcd = (a, b) => {
        if (b == 0) return a
        return gcd(b, a % b)
    }
    console.log(gcd(5, 10))
    // 走楼梯(一个台阶总共有n级台阶,如果一次可以跳1,2,
    //问有多少种可能
    const solve=n=>{
        if(n==1)  return 1
        if(n==2)  return 2
        return solve(n - 1) + solve(n - 2)
    }
    console.log(solve(2))
    
    //归并排序
    const mergeSort = array => {
        if (array.length < 2) return array
        let mid = Math.floor(array.length / 2)
        let left = array.slice(0, mid)
        let right = array.slice(mid)
        return merge(mergeSort(left), mergeSort(right))
    }
    const merge = (left, right) => {
        let result = []
        while (left.length > 0 && right.length > 0) {
            if (left[0] < right[0]) {
                result.push(left[0])
            } else {
                result.push(right[0])
            }
        }
        return result.concat(left).concat(right)
    }
    

    852 山脉数组的峰顶索引

    const pack=array=>{
        let i=0
        while (i < array.length - 1) {
            if (array[i] > array[i+1]) {
                return i
            }
            i++
        }
        return -1
    }
    console.log(pack([1, 8, 10, 4]))
    

    Proxy

    用于修改某些操作的默认行为,(拦截)(代理)

    const proxy=new Proxy(target,hanler)

    //  target  表示拦截的对象,handler 是用来定制拦截行为的对象
    let a = {
    name: 'zhangsan',
    age: 12
    }
    let proxy = new Proxy(a, {
    //拦截读取的属性
    get: (target, prop) => 35
    })
    console.log(proxy.name)
    //35
    

    handler没有设置,等同于直接通向源对象

    let proxy1 = new Proxy(a, {})
    proxy1.a='b'
    console.log(a)
    //{ name: 'zhangsan', age: 12, a: 'b' }
    

    Proxy实例的方法

    get方法

    接受三个参数:目标对象,属性名,proxy实例本身

    let preson={
    name:'zhangsan'
    }
    let proxy=new Proxy(preson,{
    get:(target,props,p)=>{
     if (props in target) {
       return target[props]
     }else{
       return ('哥哥报错了')
     }
    }
    })
    //如果没有拦截,访问不存在的属性,只会返回undefined
    console.log(proxy.aaa)
    //get方法可以继承
    let p1=Object.create(proxy)
    console.log(p1.aaa)
    //get拦截,实现数组读取负数索引
    const createArray = (...array) => {
    let target = []
    target.push(...array)
    return new Proxy(target, {
     get: (target, prop) => {
       if (Number(prop) < 0) {
         prop = String(target.length + Number(prop))
       }
       return Reflect.get(target,prop,p)
     }
    })
    }
    let p = createArray('a', 'n', 'b')
    console.log(p[-2]) //n
    

    set方法

    接受四个参数,依次为目标对象,属性名,属性值,proxy实例本身

    //设置一个对象不大于200且必须为整数
    let preon=new Proxy({},{
      set(target,prop,value){
        if(prop=='age'){
          if (value > 200||typeof(value)!='number') {
           throw new Error('报错了')
          }
        }
      }
    })
    preon.age='a'
    console.log(p)
    

    Reflect

    Reflect 对象的方法与Proxy对象的方法一一对应

    Reflect.get(target,props,args) 参数是(目标对象,属性,源对象)

    let myObjer={
    	foo:1,
    	bar:2,
    	get baz(){//get 函数的时候,会直接执行这个函数
    	 return this.foo+this.bar
    	}
    }
    console.log(Reflect.get(myObjer, 'foo'))//1
    //改变this的指向从而改变这个值(源对象是用来改变this指向的)
    let a = {
      foo: 3,
      bar: 4
    }
    console.log(Reflect.get(myObjer, 'baz', a))// 7
    

    Reflect.set(target,prop,vlaue,args) 参数目标对象,键,值,源对象

    var myObject = {
      foo: 1,
      set bar(value) {
        return this.foo = value
      },
      set(value) {
        return this.foo = value
      }
    }
    console.log(myObject.foo)//1
    //原生方法
    myObject.set(3)
    console.log(myObject.foo)//3
    //Reflect.set
    Reflect.set(myObject, 'bar', 2)
    console.log(myObject.foo)//2
    //改变this指向
    //给属性设置赋值函数,则把赋值函数的this绑定给源对象(a)
    let a = {
      foo: 100//函数执行后,也就是this.foo=2
    }
    Reflect.set(myObject, 'bar', 2, a)
    console.log(a.foo)//2
    

    Reflect.has(target,prop)

    Reflect.has 方法对应 prop in obj

    let myObject={
      foo:1
    }
    //原生
    console.log('foo' in myObject)
    //新写法
    console.log(Reflect.has(myObject, 'foo'))
    //第一个参数不是对象会报错
    

    Reflect.deleteProperty(target,prop)

    等同于delete target[prop] 用于删除对象的属性,如果target不是对象会报错

    let myObject={
      foo:1
    }
    //就写法
    delete myObject.foo
    Reflect.deleteProperty(myObject,'foo')
    console.log(myObject)
    

    Reflect.construct(target,args)

    等同于new,如果target不是函数会报错

    function Greeting(name) {
      this.name=name
    }
    const a=new Greeting('zhangsan')
    console.log(a.name)
    //new的另一种写法
    const b=Reflect.construct(Greeting,['zhangsan'])
    console.log(b.name)
    
    

    Reflect.getprototypeOf(target)

    Reflect.getPrototypeOf 方法用于读取对象的__proto__属性

    function Greeting(name) {
      this.name=name
    }
    
    const a=new Greeting('zhangsan')
    console.log(Object.getPrototypeOf(a) == Greeting.prototype)
    //新写法
    console.log(Reflect.getPrototypeOf(a) == Greeting.prototype)
    

    两个的区别

    Reflect.getPrototypeOf 如果不是对象会报错

    Object.getPrototypeOf 会把这个参数转为对象,然后再运行

    Reflect.setPrototypeOf(obj,newProto)

    设置目标对象的原型

    对应Object.setPrototypeOf(obj,newProto),他返回一个布尔值,表示是否设置成功

    const myObj = {};
    //原生
    Object.setPrototypeOf(myObj,Array.prototype)
    //新写法
    Reflect.setPrototypeOf(myObj,Array.prototype)
    console.log(myObj.length)//0
    

    Reflect.apply(func,thisArg,args)

    等同于Function.prototype.apply.call()

    const array = [1, 2, 3, 4, 4, 5]
    console.log(Math.max.apply(undefined,array)) //5
    console.log(Math.max.apply(null,array)) //5
    console.log(Object.prototype.toString.call([]))
    //[object Array]
    console.log(Reflect.apply(Math.min,undefined, array))
    console.log(Reflect.apply(Object.prototype.toString,null, array))
    

    Reflect.defineProperty(target,prop,attributes)

    等同于Object.defineProperty

    function MyDate(){
    
    }
    Object.defineProperty(MyDate,'num',{
      value:()=>Date.now()
    })
    console.log(MyDate.num())
    
    Reflect.defineProperty(MyDate,'now',{
      value:()=>Date.now()
    })
    console.log(MyDate.now())
    

    如果第一个参数不是对象,会报错

    Reflect.getOwnPropertyDescriptor(target,prop)

    用于得到指定属性的描述对象

    let myObject={
      name:'zhangsan'
    }
    //用于得到指定属性的描述对象
    console.log(Object.getOwnPropertyDescriptor(myObject, 'name'))
    /*{ value: 'zhangsan',
      writable: true,
      enumerable: true,
      configurable: true }*/
    //Reflect
    console.log(Reflect.getOwnPropertyDescriptor(myObject, 'name'))
    

    Reflect.isExtensible(target)

    方法等同于Object.isExtensible 返回一个布尔值,表示当前对象是否扩展

    Reflect.ownKeys(target)

    返回对象的所有属性

    let a={
        foo:1,
        bar:2
    }
    Reflect.ownKeys(a)
    

    前端开发规范

    命名规范

    1. 目录命名

    vue的项目,组件目录名,使用大驼峰命名leftBar

    JS,css,html文件命名:使用下划线 account_model.js

    1. HTML规范

    属性上使用双引号

    属性民全小写,用中划线(-)做分割符

    不要再自动闭合标签结尾处使用斜线<br>

    数组方法

    二分搜索

    通过值查索引

    const binarySearch = (arr, val, start = 0, end = arr.length - 1) => {
      if (start > end) return -1;
      const mid = Math.floor((end - start) / 2)
      if (arr[mid] > val) return binarySearch(arr, val, start, mid - 1)
      if (arr[mid] < val) return binarySearch(arr, val, start + 1, mid)
      return mid
    }
    console.log(binarySearch([1, 3, 4, 4, 5, 6, 7, 8, 9, 12], 3))
    

    算字符串的重复次数

    算a,b,c,总共重复了多少次
    const countStr = str => str.match(/[abc]/gi).length
    console.log(countStr('abcabsssabc'))
    

    求length=7的斐波那契的数组

    const fibonacciUntilNum = num => {
      return Array.from({ length: num })
        .reduce(
          (acc, val, i) => acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i), []
        )
    }
    console.log(fibonacciUntilNum(10))
    //[ 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 ]
    

    判断是不是Armstrong数

    // a*a*a+b*b*b+c*c*c=abc  求出所有的这三个数,也叫Armstrong数
    const isArmstrongNumber = digits => {
      return (
        arr => arr.reduce((acc, val) => acc + Number(val) ** arr.length, 0) == digits
      )
      (String(digits).split(''))
    }
    console.log(isArmstrongNumber(1634))
    

    对象解构求值

    const state = {
      B: 2,
      C: 1
    };
    const reducer3 = (state, payload) => {
      return ({
        ...state,
        B:state.B+payload,
        C:state.C*payload
      })
    }
    console.log(reducer3(state, 3))
    

    !~

    !~[1, 2, 3, 4, 5,].indexOf(8)   //true
    不存在就为true
    其实可以用some
    console.log(![1, 2, 3, 4, 5,].some(val => val == 9))
    

    不调换顺序判断,第二个字符串字段是否包含第一个字符串的字段

    const isStr = (target, str) => {
      return [...str].reduce((acc, val) =>
          val == (target[acc] || '') ? acc + 1 : acc
        , 0) == target.length
    }
    console.log(isStr('ca', 'abc'))//false
    console.log(isStr('ac', 'abc'))//true
    

    查看原型是什么类型

    const getType = v =>
      [,null].some(val => val == v)
        ?v
        :v.constructor.name.toLowerCase()
    
  • 相关阅读:
    iptables dnat不通
    os.system()和os.popen()
    mysql登录提示ERROR 1524 (HY000): Plugin 'unix_socket' is not loaded解决方法
    SpringBoot之web开发
    基于MQ的分布式事务解决方案
    Docker核心技术
    [Java]Object有哪些公用方法?
    zookeeper
    单例模式的几种实现方式及优缺点
    并发编程之Synchronized原理
  • 原文地址:https://www.cnblogs.com/fangdongdemao/p/11213272.html
Copyright © 2020-2023  润新知