前端必會的程式碼段

Mrlgm發表於2019-03-23

前記

前端不能說必會吧,emm,最好都會,其實每個都有很多種寫法,可以自行擴充套件

程式碼

debounce

function debounce(fn,wait = 50){
    let timeId
    return function(){
        if(timeId){
            clearTimeout(timeId)
        }
        timeId = setTimeout(fn(...arguments),wait)
    }
}
複製程式碼

throttle

function throttle(fn, wait = 100) {
  let pre
  return function () {
    if (!pre) {
      pre = +new Date
    }
    let now = +new Date
    if (now - pre > wait) {
      pre = now
      fn()
    }
  }
}
複製程式碼

flat

const flatten1 = function(arr){
    while(arr.some(item=>Array.isArray(item))){
        arr = [].concat(...arr)
    }
    return arr
}

const flatten2 = function(arr){
    return arr.reduce((acc,cur)=>{
        return Array.isArray(cur)?[...acc,...flatten2(cur)]:[...acc,cur]
    },[])
}

const flatten3 = function(arr){
    return arr.toString().split(',')//注意適用型別
}
複製程式碼

binary_search

var search = function(nums, target) {
    let low = 0
    let high = nums.length
    let mod
    
    while(high > low){
        mod = Math.floor((low + high) / 2)
        if(nums[mod] === target){
            return mod
        }else if(nums[mod] > target){
            if(high !== mod){
                high = mod
            }else{
                return -1
            }
        }else{
            if(low !== mod){
                low = mod
            }else{
                return -1
            }
        }
    }
    return -1
};
複製程式碼

mycall

Function.prototype.myCall = function (context, ...arg) {
  if (typeof this !== 'function') {
    throw new Error('不是函式')
  }
  let fn = Symbol()
  context[fn] = this
  let result = context[fn](...arg)
  return result
}
複製程式碼

myapply

Function.prototype.myCall = function (context, ...arg) {
  if (typeof this !== 'function') {
    throw new Error('不是函式')
  }
  let fn = Symbol()
  context[fn] = this
  let result = context[fn](arg)
  return result
}
複製程式碼

mybind

Function.prototype.myBind = function (context, ...arg) {
  const _this = this
  return function F() {
    if (this instanceof F) {
      return new _this(...arg, ...arguments)
    }
    return _this.apply(context, [...arg, ...arguments])
  }
}
複製程式碼

new

function create(Constructor, ...arg) {
  let obj = {}
  obj = Object.create(Constructor.prototype)
  let result = Constructor.apply(obj, arg)
  return typeof result === 'object' ? result : obj
}
複製程式碼

sleep

function sleep(ms) {
  return new Promise((resolve) => {
    setTimeout(resolve, ms)
  })
}

async function time() {
  console.log(111)
  await sleep(5000)
  console.log(222)
}
複製程式碼
function sleep2(ms) {
  let now = new Date().getTime()
  let ful = new Date().getTime()
  while (ful - now < ms) {
    ful = new Date().getTime()
  }
}

console.log(111)
sleep2(5000)
console.log(222)
複製程式碼

deepClone

function deepClone(obj){
    function isObj(obj){
        return(typeof obj === 'object' || typeof obj === 'function') && typeof obj !== null
    }

    if(!isObj(obj)){
        throw new Error('不是物件')
    }

    let isArray = Array.isArray(obj)
    let newObj = isArray ? [...obj] : {...obj}

    Reflect.ownKeys(newObj).forEach((key)=>{
        newObj[key] = isObj(obj[key]) ? deepClone(obj[key]) : obj[key]
    })

    return newObj
}
複製程式碼

quickSort

function quick(arr){
    if(arr.length <= 1){return arr}
    let index = Math.round(Math.random() * (arr.length - 1))
    let right = []
    let left  = []
    for(let i = 0; i < arr.length; i++){
        if(i !== index){
            if(arr[i] <= arr[index]){
                right.push(arr[i])
            }else{
                left.push(arr[i])
            }
        }
    }
    return quick(right).concat(arr[index],quick(left))
}
複製程式碼

bubbleSort

function swap(arr, i, j){
    let temp = arr[i]
    arr[i] = arr[j]
    arr[j] = temp
}

function bubble(arr){
    for(let i = arr.length - 1; i >= 0; i--){
        for(let j = 0; j < i; j++){
            if(arr[j] > arr[j+1]){
                swap(arr, j, j+1)
            }
        }
    }
    return arr
}
複製程式碼

selectionSort

function selectionSort(arr){
    let length = arr.length
    let minIndex, temp
    for(let i = 0; i < length; i++){
        minIndex = i
        for(let j = i+1; j < length; j++){
            if(arr[minIndex] > arr[j]){
                minIndex = j
            }
        }
        temp = arr[i]
        arr[i] = arr[minIndex]
        arr[minIndex] = temp
    }
    return arr
}
複製程式碼

trim

function trim(str){
    return str.replace(/^\s* | \s*$/g, '')
}
複製程式碼

unique

function unique1(arr){
    return arr.filter((item,index,arr)=>{
        return arr.indexOf(item) === index
    })
}

function unique2(arr){
    return [...new Set(arr)]
}

function unique3(arr){
    let obj = {}
    let array = []
   for(let i = 0; i < arr.length; i++){
       obj[arr[i]] = 0
   }

   for(let key in obj){
       array.push(key)
   }

   return array
}
複製程式碼

MyPromise && ajax

const PENDING = 'pending'
const RESOLVED = 'resolved'
const REJECTED = 'rejected'

function MyPromise(fn){
    const that = this
    that.state = PENDING
    that.value = null
    that.resolvedCallbacks = []
    that.rejectedCallbacks = []
    
    function resolve(value){
        if(that.state === PENDING){
            that.state = RESOLVED
            that.value = value
            that.resolvedCallbacks.map(cb => cb(value))
        }
    }

    function reject(value){
        if(that.state === PENDING){
            that.state = REJECTED
            that.value = value
            that.rejectedCallbacks.map(cb => cb(value))
        }
    }
    
    try{
        fn(resolve,reject)
    } catch(e){
        reject(e)
    }

}

MyPromise.prototype.then = function(onFulfilled, onRejected){
    const that = this
    onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : v => v
    onRejected = typeof onRejected === 'function' ? onRejected: r => {throw r}
    if (that.state === PENDING) {
        that.resolvedCallbacks.push(onFulfilled)
        that.rejectedCallbacks.push(onRejected)
    }
    if (that.state === RESOLVED) {
        onFulfilled(that.value)
    }
    if (that.state === REJECTED) {
        onRejected(that.value)
    }
}

function get(url){
    return new MyPromise((resolve, reject)=>{
        let xhr = new XMLHttpRequest

        xhr.open('get', url, true)

        xhr.onreadystatechange = function(){
            if(this.readyState === 4){
                if(this.status === 200){
                    resolve(this.response, this)
                }else{
                    let resJson = { code: this.status, response: this.response }
                    reject(resJson, this)
                }
            }
        }
        xhr.send()
    })
}

get('http://api.wwnight.cn').then((value, that)=>{
    console.log(value)
})
複製程式碼

lazyLoad

這個有兩種方法,都可以選

html

<body>
<div style="height:100vh;width: 100vw;"></div>
  <div>
    <img class="my-photo" alt="" data-src="http://img.wwnight.cn//image/1.png">
  </div>
  <div>
    <img class="my-photo" alt="" data-src="http://img.wwnight.cn//image/2.png">
  </div>
  <div>
    <img class="my-photo" alt="" data-src="http://img.wwnight.cn//image/3.png">
  </div>
</body>
複製程式碼

第一種

function checkImgs(){
    const imgs = Array.from(document.querySelectorAll('.my-photo'))
    imgs.forEach(item => io.observe(item))
}

function loadImg(el){
    if(!el.src){
        const source = el.dataset.src
        el.src = source
    }
}

const io = new IntersectionObserver(ioes => {
    ioes.forEach((ioe)=>{
        const el = ioe.target
        const intersectionRatio = ioe.intersectionRatio
        if(intersectionRatio > 0 && intersectionRatio <= 1){
            loadImg(el)
        }
        el.onload = el.onerror = ()=>io.unobserve(el)
    })
})
複製程式碼

第二種

function inSight(el) {
  const bound = el.getBoundingClientRect()
  const height = window.innerHeight

  return bound.top < height
}

const imgs = document.querySelectorAll('.my-photo')

function checkImg() {
  console.log(1)
  imgs.forEach(img => {
    if (inSight(img)) {
      loadImg(img)
    }
  })
}

function loadImg(el) {
  if (!el.src) {
    const source = el.dataset.src
    el.src = source
  }
}

function throttle(fn, wait = 100) {
  let pre
  return function () {
    if (!pre) {
      pre = +new Date
    }
    let now = +new Date
    if (now - pre > wait) {
      pre = now
      fn()
    }
  }
}

window.onscroll = throttle(checkImg)
複製程式碼

後記

暫時寫了這麼多,有更新的話會再更新的

相關文章