前端常见的笔试题

726 阅读1分钟

数组去除重复元素

let arr = [1,2,33,4,5,3,2,1,5,6,4,3]

// 方法一
function fn(arr) {
    let newArr = []
    for (let i = 0; i < arr.length; i++) {
        if (newArr.indexOf(arr[i]) === -1) {
            newArr.push(arr[i])
        }
    }
    return newArr
}

// 方法二、
function fn(arr){
  for(let i = 0; i < arr.length; i++){
    for(let j = i + 1; j < arr.length; j++){
     if( arr[i] === arr[j] ){
       arr.splice(j,1)
       j--
     }
    }
  }
  return arr
}


//输出 [1, 2, 33, 4, 5, 3, 6]

将数组扁平化

/**
 * 数组扁平化
 * @param {array} array 
 */
function flatter(array) {
  const result = []
  array.forEach(item => {
    if (Array.isArray(item)) {
      const flatterItem = flatter(item)
      flatterItem.forEach(n => result.push(n))
    } else {
      result.push(item)
    }
  })
  return result
}

function flatten1(array) {
  let result = []
  array.forEach(item => {
    if (Array.isArray(item)) {
      const flatterItem = flatten1(item)
      result = result.concat(flatterItem)
    } else {
      result = result.concat(item)
    }
  })
  return result
}

// 测试
console.log(flatten1([]))
console.log(flatten1([1, 2, 3]))
console.log(flatten1([1, 2, [3]]))
console.log(flatten1([1, 2, [3, [4, [5, [6]]]]]))

将数组扁平化且去除重复的元素,最后升序输出

let arr = [1, [1, [2]], [3, 4], 7, 4, [2, 3, [4, 5, [2, 2, 1, 5, 4, 3, 8]]]]

// 方法一
function fn(arr) {
    let newArr = arr.flat(Infinity)
    newArr = [... new Set(newArr)]
    return newArr.sort((a, b) => a - b)
}

// 方法二、
function fn(arr) {
    let str = JSON.stringify(arr)
    let newArr = JSON.parse(`[${str.replace(/\[|\]/g, '')}]`)
    let arr1 = newArr.filter((item, index) => newArr.indexOf(item) === index)
    return arr1.sort((a, b) => a - b)
}

[ 1, 2, 3, 4, 5, 7, 8]

深拷贝

// 方法一、 let obj1 = JSON.parse(JSON.stringify(obj))
// 方法二
function deepCopy(obj = {}){
    if(typeof obj !== "object" || obj == null){
        return obj
    }


    let result 
    if(result instanceof Array){
        result = []
    }else{
        result = {}
    }

    for(const key in obj){
        if(Object.hasOwnProperty.call(obj, key)){
            result[key] = deepCopy(obj[key])
        }
    }

    return result

}

输入一个字符串,分割该字符串的每个字符然后重新排列,输出可能排列的所有方式,如:输入 'ab',输出 'ab' 'ba'

function fn(str){
    let temp = []
    if(str.length === 0) return ''
    if(str.length === 1) {
      return str
    }else{
      let obj = {}
      for(let i = 0; i < str.length; i++){
        let s = str[i]
        if(!obj[s]){
          let newStr = str.slice(0,i) + str.slice(i+1,str.length)
          let l = fn(newStr)
          for(let j = 0; j < l.length; j++){
            let t = s + l[j]
            temp.push(t)
          }
          obj[s] = true
        }
      }
    }
    return temp
  }
  
  console.log(fn('abc'));

实现冒泡排序

let arr = [1,22,333,2,4,66,4,3,2,3,67,5,43,7,5,4]

function fn(arr){
  for(let i = 0; i < arr.length; i++){
    for(let j = i+1; j < arr.length; j++){
      if(arr[i] > arr[j]){
        let item = arr[i]
        arr[i] = arr[j]
        arr[j] = item
      }
    }
  }
  return arr
}

console.log(fn(arr));

实现快速排序

/**
 * 快速排序 数组二分,基于中间位置的数字,小数放左边,大数放右边
 * @param {array} array 
 */
function quicksort(array) {
  if (array.length === 0) return array
  // 找出数组中间位置的下标
  const index = Math.floor((array.length - 1) / 2)
  const left = []
  const right = []
  const center = array[index]
  for (let i = 0; i < array.length; i++) {
    if (array[i] <= center && i !== index) {
      left.push(array[i])
    }
    if (array[i] > center) {
      right.push(array[i])
    }
  }
  return [...quicksort(left), center, ...quicksort(right)]
}

let arr = [1, 22, 333, 2, 4, 66, 4, 3, 2, 3, 67, 5, 43, 7, 5, 4]

const newArr = quicksort(arr)

console.log(arr, newArr)

找出数组中出现最多的数字

function findMostRepetitionsNumber(arr) {
  let num = null
  let count = 1
  const obj = {}
  for (let i = 0; i < arr.length; i++) {
    if (!obj[arr[i]]) {
      obj[arr[i]] = 1
    } else {
      obj[arr[i]] += 1
      if (obj[arr[i]] > count) {
        count = obj[arr[i]]
        num = arr[i]
      }
    }
  }
  return {
    num,
    count,
  }
}

const arr = [3, 5, 6, 6, 6, 6, 5, 9, 8, 10, 5, 7]

console.log(findMostRepetitionsNumber(arr))

手写call ,apply ,bind

    Function.prototype.myCall = function (ctx, ...args) {
        ctx.fn = this;
        ctx.fn(...args)
        delete ctx.fn
    }

    Function.prototype.myApply = function (ctx, args = []) {
        if (args && !Array.isArray(args)) {
            throw (new Error('参数需为数组'))
        }
        ctx.fn = this;
        ctx.fn(...args)
        delete ctx.fn
    }
    Function.prototype.myBind = function (ctx, ...args) {
        console.log(args);
        return (...args1) => {
            ctx.fn = this;
            ctx.fn(...args1.concat(args))
        }
    }
    function a(...args) {
        console.log(this.name);
        console.log(...args);
    }

    a.myCall({ name: "肖勋留" }, 1, 2, 3, 4)
    a.myApply({ name: "肖勋留" }, [1, 2, 3, 4])
    let b = a.myBind({ name: "肖勋留" }, 1, 2, 3, 4)
    b(5)

手写ajax

    function ajax({ type, url, data = null }) {
        return new Promise((resolve, reject) => {
            const xhr = new XMLHttpRequest();
            xhr.open(type.toUpperCase(), url, true);
            xhr.onreadystatechange = function () {
                if (xhr.readyState === 4) {
                    if (xhr.status === 200) {
                        resolve(xhr.responseText);
                    } else {
                        reject('请求失败')
                    }
                }
            }
            data = data ? JSON.stringify(data) : data;
            xhr.send(data)
        })
    }

    //测试
    ajax({ type: "get", url: "https://autumnfish.cn/api/joke/" })
        .then(res => {
            console.log(res);
        })
        .catch(error => {
            console.log(error);
        })
    const data = {
        page: "1",
        count: "5"
    }
    ajax({ type: "post", url: "https://api.apiopen.top/getWangYiNews" }, data)
        .then(res => {
            console.log(res);
        })
        .catch(error => {
            console.log(error);
        })

防抖节流

    //防抖
    function debounce(fn, delay = 500) {
        let time = null;
        return function () {
            if (time) {
                clearTimeout(time)
            }
            time = setTimeout(() => {
                fn.apply(this, arguments);
                time = null
            },delay)
        }
    }

    //节流
    function throttle(fn, delay = 500) {
        let time = null;
        return function () {
            if (time) {
                return
            }
            time = setTimeout(() => {
                fn.apply(this, arguments);
                time = null
            },delay)
        }
    }

手写isEqual

const obj1 = {
    a: 100,
    b: {
        c:11,
        x: 110,
        y: 200,
    }
}

const obj2 = {
    a: 100,
    b: {
        y: 200,
        x: 110,
        c:11
    },

}
//判断是否对象或者是数组
function isObjectOrArray(obj) {
    return typeof obj === 'object' && obj !== null;
}


function isEqual(obj1, obj2) {
    //判断二个参数是否有一个不是对象就返回他们的比较值
    if (!isObjectOrArray(obj1) || !isObjectOrArray(obj2)) {
        return obj1 === obj2
    }
    //如果二个都是对象,且引用地址相等
    if (obj1 === obj2) {
        return true;
    }
    //比较二个参数的keys是否相等
    if (Object.keys(obj1).length !== Object.keys(obj2).length) {
        return false;
    }
    //基于obj1递归比较value
    for (const key in obj1) {
        const res = isEqual(obj1[key], obj2[key]);
        if (!res) return false;
    }

    return true

}

console.log(isEqual(obj1, obj2));

手写EventBus

class EventBus {
  constructor() {
    this.stack = {}
  }
  //监听事件
  $on(event, cb) {
    // TODO: 如果当前事件存在,就push进去
    if (this.stack[event]) {
      this.stack[event].push(cb)
    } else {
      // TODO: 不存在则把它存放在一个数组中
      this.stack[event] = [cb]
    }
  }

  //发送事件
  $emit(event, ...args) {
    if (this.stack[event]) {
      this.stack[event].forEach(cb => cb(...args))
    }
  }
  //移除事件
  $off(event) {
    if (this.stack[event]) {
      delete this.stack[event]
    }
  }
  //只监听一次
  $once(event, cb) {
    const once = (...args) => {
      cb(...args)
      this.$off(event)
    }
    this.$on(event, once)
  }
}

let eventBus = new EventBus()

eventBus.$on('on', function(msg) {
  console.log(msg)
})
eventBus.$once('once', function(msg) {
  console.log(msg)
})
eventBus.$on('off', function(msg) {
  console.log(msg)
})
eventBus.$emit('on', '发布on1') //发布on1
eventBus.$emit('on', '发布on2') //发布on2
eventBus.$emit('once', '发布once') //发布once
eventBus.$emit('once', '发布once')
eventBus.$emit('off', '发布off') //发布off
eventBus.$off('off')
eventBus.$emit('off', '发布off')

简单实现promise

const PENDING = 'pending'
const RESOLVED = 'resolved'
const REJECTED = 'rejected'
class MyPromise {
  constructor(fn) {
    this.state = PENDING
    this.value = null
    this.resolvedCallback = []
    this.rejectedCallback = []
    this.resolve = this.resolve.bind(this)
    this.reject = this.reject.bind(this)
    this.then = this.then.bind(this)
    this.catch = this.catch.bind(this)
    try {
      fn(this.resolve, this.reject)
    } catch (e) {
      this.reject(e)
    }
  }
  resolve(value) {
    if (this.state === PENDING) {
      this.state = RESOLVED
      this.value = value
      this.resolvedCallback.map(cb => cb(this.value))
    }
  }

  reject(err) {
    if (this.state === PENDING) {
      this.state = REJECTED
      this.value = err
      this.rejectedCallback.map(cb => cb(this.value))
    }
  }
  then(onFulfilled, onRejected) {
    onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : v => v
    onRejected = typeof onRejected === 'function' ? onRejected : e => e
    if (this.state === PENDING) {
      this.resolvedCallback.push(onFulfilled)
      this.rejectedCallback.push(onRejected)
    }
    if (this.state === RESOLVED) {
      onFulfilled(this.then)
    }
    if (this.state === REJECTED) {
      onRejected(this.then)
    }
    return this
  }

  catch(cb) {
    return this.then(null, cb)
  }
}
new MyPromise((resolve, reject) => {
  setTimeout(() => {
    resolve(1)
  }, 0)
})
  .then(value => {
    console.log(value)
  })
  .catch(err => {
    console.log(err)
  })

new MyPromise((resolve, reject) => {
  setTimeout(() => {
    try {
      let n = 1
      resolve(n())
    } catch (e) {
      reject(e)
    }
  }, 0)
})
  .then(value => {
    console.log(value)
  })
  .catch(err => {
    console.log(err)
  })