玩命加载中 . . .

备战大厂前端实习之手写代码篇


前端面试题系列文章:

手写代码

手写 Object.create

作用:将传入的对象作为原型

function _create(obj) {
  function F();
  F.prototype = obj;
  return new F();
}

手写 instanceof 方法

instanceof 运算符用于判断构造函数的 prototype 属性是否出现在对象的原型链中的任何位置。

function _instanceof(left, right) {
  if (!((typeof left === 'function' || (typeof left === 'Object' && left)) && typeof right === 'function')) {
    throw new Error('传入的参数不符合规范');
  }

  let left = Object.getPrototypeOf(left);
  const right = right.prototype;
  while (true) {
    if (!left) return false;
    if (left === right) return true;
    
    // 如果没有找到,就继续从其原型上找,Object.getPrototypeOf 方法用来获取指定对象的原型
    left = Object.getPrototypeOf(left);
  }
}

手写 call

Function.prototype._call = function(context, ...arg) {
  context = context || window;
  if (typeof context !== 'object') {
    context = Object.create(null);
  }
  const fn = Symbol('fn');
  context[fn] = this;
  const result = context[fn](...arg);
  delete context[fn];
  return result;
}

手写 apply

Function.prototype._apply = function(context, arg) {
  context = context || window;
  if (typeof context !== 'object') {
    context = Object.create(null);
  }
  const fn = Symbol('fn');
  context[fn] = this;

}

手写 bind

Function.prototype._bind = function(context, ...arg) {
  let obj = null;
  let constructor = Array.prototype.shift.call(arguments);
  let result = null;
  if (typeof constructor !== 'function') {
    return;
  }
  obj = Object.create(constructor.prototype);
  result = constructor.apply(obj, arguments);
  let flag = result && (typeof result === 'object' || typeof result == 'function')
  return flag ? result : obj;
}

JS 实现洋葱模型

一维数组转树桩

function arrayToTree(arr) {
  const res = [];
  const arrMap = {};
  
  for (const item of arr) {
    arrMap[item.id] = {...item, children: []};
  }

  for (const item of arr) {
    const id = item.id;
    const parent = item.parent;
    const treeItem = itemMap[id];
    if (!parent) {
      res.push()
    }
  }
}

手写防抖、节流

  1. 防抖

    function debounce(fn, wait) {
      let timeout = null;
    
      return function () {
        let _this = this;
        let args = arguments;
        if (timeout) {
          clearTimeout(timeout);
          timeout = null;
        }
        timeout = setTimeout(() => {
          fn.apply(_this, args);
        }, wait);
      }
    }
  2. 节流

方式一:使用时间戳

function throttle(fn, wait) {
  let previous = 0;
  return function () {
    let now = Date.now();
    const _this = this;
    const args = arguments;
    
    if (now - previous > wait) {
      fn.apply(_this, args);
      previous = now;
    }
  }
}

方式二:使用定时器

function throttle (fn, wait) {
    let timeout = null;
    return function () {
        const _this = this;
        const args = arguemnts;
        
        if (!timeout) {
            timeout = setTimeout(() => {
                fn.apply(_this, args);
                timeout = null;
            }, wait);
        }
    }
}

函数柯里化

function curry(fn, args) {
  let len = fn.length;
  args = args || [];
  return function() {
    let subArgs = args.slice(0);
    for (let i = 0; i < )
  }
}

编程题:有一个数组 idArr ,长度是 100; 现在要调用一个接口 fetch 去查询每个数组元素 id

对应的 name;要求要分批调用,每批最多只能查询 10 个,以此实现一个 batch 函数;
进阶1:怎么判断批量操作是否都成功了,还是有的失败了;
进阶2:实现能找到查询失败的数据,并重新批量发接口重试

const idArr = [{
  id: '1',
}, {
  id: '2',
}, {
  id: '100',
}];

fetch: (params: {id: string}[]) => Promise<{id: string; name: string}[]>

const batch = (idArr: {id: string}[]): Promise<{id: string; name: string}[]>[] => {

};

数组扁平化

写一个消息的发布与订阅

字符串驼峰命名转_连接


文章作者: hcyety
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 hcyety !
评论
  目录