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()
posted @ 2019-07-19 14:56  猫神甜辣酱  阅读(616)  评论(0编辑  收藏  举报