lewenweijia / notes

🏊 dive dive diving
1 stars 0 forks source link

手写实现: 系列 #22

Open lewenweijia opened 5 years ago

lewenweijia commented 5 years ago
// 前置知识
const proto = { };
Object.getPrototypeOf(Object.create(proto)) === proto; // true

// 实现instanceOf
function isInstanceOf(child, constructor) {
  const proto = Object.getPrototypeOf(child);
  if (proto === null) return false;
  if (proto === constructor.prototype) return true;
  return isInstanceOf(proto, constructor);
}

// 实现new
function myNew(constrcutor, ...args) {
  const obj = {};
  Object.setPrototype(obj, fn.prototype);

  constructor.apply(obj, args);

  return obj;
}

// 实现原型继承
function myExtends(parent, child) {
  child.prototype = Object.create(parent.prototype);

  // or
  function noop() {}
  noop.prototype = parent.prototype;
  child.prototype = new noop();
}
function flatten(arr) {
  return arr.reduce((acc, i) => Array.isArray(i) ? [...acc, ...flatten(i)] : [...acc, i]
}
lewenweijia commented 5 years ago
function memo(fn) {

  const cache = {};
  return function (...args) {

    const key = args.toString();

    if (!cache[key]) cache[key] = fn(...args);

    return cache[key];
  }
}
lewenweijia commented 5 years ago
// 实现apply
Function.protype.myApply = function(context, args) {
  context.fn = this;
  const result = context.fn(..args);

  delete context.fn

  return result;
}

// 实现call
Function.prototype.myCall = (thisArg, ...args) => {
  thisArg.fn = this;
  const result = thisArg.fn(...args);

  delete thisArg.fn;
  return result;
}

//  实现bind
Function.prototype.bind = (thisArg, ...args1) => {

  const that = this;
  function bound(...args) {
    thisArg.fn = that;
    const result = thisArg.fn(...[...args1, ...args2]);

    delete thisArg.fn;
    return result;
  }

  return bound;
}
lewenweijia commented 5 years ago
// 实现debounce
function debounce(fn, delay) {

  let timer = null;
  return (...args) => {
    if (timer) clearTimeout(timer);

    timer = setTimeout(() => {
      fn.call(this, ...args);

      clearTimeout(timer);
    }, delay);
  }
}

// 实现throttle
function debounce(fn, delay) {

  let running = false;
  return (...args) => {
    if (running) return;

    running = true;
    setTimeout(() => {
      fn.call(this, ...args);

      running = false;
    }, delay);
  }
}
lewenweijia commented 5 years ago

面试题综合?: 大数相加

// 大数相加
function bigNumberSum(a, b) {
  // padding
  let cur = 0;
  while (cur < a.length || cur < b.length) {
    if (!a[cur]) a = "0" + a;
    else b = "0" + b;

    cur++;
  }

  let carry = 0;
  const res = [];

  for (let i = a.length - 1; >= 0; i--) {
    const sum = carry + a[i] + b[i];
    if (sum > 9) {
      carry = 1;
    } else {
      carry = 0;
    }

    res[i] = sum % 10;
  }

  if (carry) res.unshift(1);

  return res.join("");
}
lewenweijia commented 5 years ago
// curry
function curry(fn) {
  const context = this;
  function inner(...args) {
    if (args.length === fn.length) return fn.call(context, ...args);
    return (...innerArgs) => inner.call(context, ...args, ...innerArgs);
  }

  return inner;
}

// usage:
function test(a, b, c) {
  console.log(a, b, c);
}
lewenweijia commented 5 years ago
// 实现深拷贝
function deepCopy(o) {
  if (typeof o !== 'object' || o === null) return o;

  let n;
  if (Array.isArray(o)) {
    n = Array(o.length);
    o.forEach((v, i) => n[i] = deepCopy(v));
  } else if (!Array.isArray(o)) {
    n = {};
    Object.keys(o).forEach(key => {
      n[key] = deepCopy(o[key]);
    });
  }

  return n
}
lewenweijia commented 5 years ago
// 遍历一颗DOM树
function traversal(root) {
  if (root.nodeType === Node.ELEMENT_NODE) {
    console.log(root.tagName);
  }

  for (const child of root.childNodes) {
    traversal(child);
  }
}
lewenweijia commented 5 years ago
// new 操作符做了什么
// 1. 创建一个新对象
// 2. 将对象的原型绑定到constrcutor.prototype上
// 3. constructor的执行上下文绑定为该新对象并执行函数
// 4. constructor返回对象引用
lewenweijia commented 5 years ago
// es5 es6技巧对比
// 1. 类数组转数组
[...arguments];
Array.prototype.slice.call(arguments);
lewenweijia commented 5 years ago
// 标准vdom操作
render -> diff -> patch
lewenweijia commented 5 years ago
// 大数据量的问题
// 1. 哈希求模映射成小文件   %10 -> 

// trie树的用途
//  优点: 最大限度地减少无谓的字符串比较,查询效率比哈希表高。
// 1. 词频统计
// 2. 前缀匹配(补全)

// 布隆过滤器, 退一步将就是位图, 位图退一步讲就是特殊哈希
lewenweijia commented 5 years ago
// es5实现map
Array.prototype.map2 = function (fn) {
  var arr = Array.prototype.slice.call(this);
  var mappedArr = [];
  for (let i = 0; i < arr.length; i++) {
    mappedArr.push(fn(arr[i], iJ));
    // mappedArr.push(fn.call(context, arr[i]));
  }

  return mappedArr;
}

// es5实现reduce
Array.prototype.reduce2 = (fn, init) => {
  const arr = Array.prototype.slice.call(this);
  let acc = init;
  for (let i = 0; i < arr.length) {
    acc = fn(acc, arr[i]);
  }

  return acc;
}

// 实现Object.create犯法
function create(proto) {
  function noop() {}
  noop.prototype = proto;

  return new noop();
}