Skip to content
本页目录

手撕代码

手写JSONP

JavaScript
const jsonp = ({ url, params, callback }) => {
  return new Promise((resolve, reject) => {
    const script = document.createElement('script')
    window[callback] = data => {
      resolve(data)
      document.body.removeChild(script)
    }
    params = { ...params, callback }
    const arr = []
    for (const key in params) {
      arr.push(`${key}=${params[key]}`)
    }
    script.src = `${url}?${arr.join('&')}`
    document.body.appendChild(script)
  })
}

封装Ajax

JavaScript
const ajax = ({ url, method = 'GET', data }) => {
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest()
    xhr.onreadystatechange = () => {
      if (xhr.readyState == 4) {
        if (xhr.status >= 200 && xhr.status < 300 || xhr.status == 304) {
          resolve(xhr.responseText)
        } else {
          reject(xhr.statusText)
        }
      }
    }
    if (method === 'POST') {
      xhr.open(method, url, true)
      xhr.responseType = 'json'
      xhr.setRequestHeader('Accept', 'application/json')
      xhr.send(data)
    } else {
      let query = ''
      for (const key in data) {
        query += `&${encodeURIComponent(key)}=${encodeURIComponent(data[key])}`
      }
      query.substring(1)
      xhr.open(method, `${url}?${query}`, true)
      xhr.send()
    }
  })
}

深拷贝

JavaScript
const deepClone = obj => {
  const getType = _o => Object.prototype.toString.call(_o)
  let ret, type = getType(obj)
  if (type === '[object Object]') {
    ret = {}
  } else if (type === '[object Array]') {
    ret = []
  } else {
    return obj
  }
  for (const key in obj) {
    const value = obj[key]
    const _type = getType(value)
    if (_type === '[oject Object]' || _type === '[object Array]') {
      ret[key] = deepClone(value)
    } else {
      ret[key] = value
    }
  }
  return ret
}

模板解析

JavaScript
const kon = [
  {
    name: '平泽唯',
    age: 14
  },
  {
    name: '秋山澪',
    age: 15
  }]
// template为模板字符串被 以${}界点划分成的元素块组成的数组
// expressions是${}计算后的值组成的数组
const templateFn = (templates, ...expressions) => {
  let ret = templates.reduce((pre, cur, idx) => {
    let expression = expressions[idx - 1]
    return pre + expression + cur
  })
  return ret.trim()
}
templateFn
  `<ul>
    <li>${kon[0].name + '-' + kon[0].age}</li>
    <li>${kon[1].name + '-' + kon[1].age}</li>
  </ul>`
// '<ul>\n    <li>平泽唯-14</li>\n    <li>秋山澪-15</li>\n  </ul>'

精度丢失

JavaScript
// 放大 - 缩小 解决浮点数精度丢失
Math.fixPrecision = (val, digit) => {
  const m = Math.pow(10, digit)
  return Math.round(val * m, 10) / m
}