面试手写第三期

一. 寄生组合继承

function clone(parent, child) {
    
    
  // 这里改用 Object.create 就可以减少组合继承中多进行一次构造的过程
  child.prototype = Object.create(parent.prototype);
  child.prototype.constructor = child;
}

function Parent() {
    
    
  this.name = 'parent';
  this.play = [1, 2, 3];
}
Parent.prototype.getName = function () {
    
    
  return this.name;
};
function Child() {
    
    
  Parent.call(this);
  this.friends = 'child';
}

clone(Parent, Child);

Child.prototype.getFriends = function () {
    
    
  return this.friends;
};

let child = new Child();
console.log(child); //{friends:"child",name:"parent",play:[1,2,3],__proto__:Parent}
console.log(child.getName()); // parent
console.log(child.getFriends()); // child

二. 千分位分隔实现

function numberWithCommas(x) {
    
    
  x = x.toString();
  var pattern = /(-?\d+)(\d{3})/;
  while (pattern.test(x)) {
    
    
    x = x.replace(pattern, '$1,$2');
  }
  return x;
}

console.log(numberWithCommas(12312122222.34));

三. 判断两个值是否相等isEqual的实现

function isEqual(x, y) {
    
    
  if (x === y) {
    
    
    return true;
  } else if (
    typeof x === "object" &&
    x !== null &&
    typeof y === "object" &&
    y !== null
  ) {
    
    
    const keysX = Object.keys(x);
    const keysY = Object.keys(y);
    if (keysX.length !== keysY.length) {
    
    
      return false;
    }
    for (const key of keysX) {
    
    
      if (!isEqual(x[key], y[key])) {
    
    
        return false;
      }
    }
    return true;
  } else {
    
    
    return false;
  }
}

let x = {
    
    
  a: '1',
  b: '2'
}
let y = {
    
    
  a: '1',
  b: '2'
}
console.log(isEqual(x, y));

四. 关于字符串编码解码进阶

countOfLetters("A2B3"); // { A: 2, B: 3 }
countOfLetters("A(A3B)2"); // { A: 7, B: 2}
countOfLetters("C4(A(A3B)2)2"); // { A: 14, B: 4, C: 4 }

function letterAddCount(target, source) {
    
    
  for (let k in source) {
    
    
    target[k] = target[k] || 0;
    target[k] += source[k];
  }
  return target;
}
function letterMultipleCount(target, multiples) {
    
    
  for (let i in target) {
    
    
    target[i] *= multiples;
  }
  return target;
}
function countOfLetters(str) {
    
    
  const regex = /[1-9]/;
  const stack = [{
    
    }];
  for (let i = 0; i < str.length; i++) {
    
    
    const ch = str[i];
    let count = 1;
    if (regex.test(str[i + 1])) count = +str[++i]; // case ( | )
    switch (ch) {
    
    
      case "(":
        stack.push({
    
    });
        continue;
      case ")":
        const pop = stack.pop();
        const last = stack[stack.length - 1];
        letterAddCount(last, letterMultipleCount(pop, count));
        continue;
    } 
    // case A-Z
    const last = stack[stack.length - 1];
    last[ch] = last[ch] || 0;
    last[ch] += count;
    console.log(stack);
  }
  return stack.pop();
}
console.log(countOfLetters("A(A3B)2"));

五. 发布订阅者模式

class EventEmitter {
    
    
  constructor() {
    
    
    this.events = {
    
    }
  }
  on(type, cb) {
    
    
    if(!this.events[type]) {
    
    
      this.events[type] = []
    }
    this.events[type].push(cb)
  }
  emit(type, ...args) {
    
    
    if(this.events[type]) {
    
    
      this.events[type].forEach(cb => {
    
    
        cb.apply(this, args);
      })
    }
  }
  once(type, cb) {
    
    
    const func = (...args) => {
    
    
      this.off(type, func);
      cb.apply(this, args);
    };
    this.on(type, func);
  }
  off(type, cb) {
    
    
    if(!cb) {
    
    
      this.events[type] = null
    } else {
    
    
      this.events[type] = this.events[type].filter(c => c != cb)
    }
  }
}

const e = new EventEmitter();
const callback2 = (data) => console.log(`${
      
      data.name}`);
 
e.on("click", callback2);
 
e.emit("click", {
    
     name: "xiaoming" });
 
e.off("click", callback2);
 
e.emit("click", {
    
     name: "lili" });

六. 实现一个函数 maxBy,根据给定条件找到最大的数组项

const maxBy = (list, keyBy) => {
    
    
  return list.slice(1).reduce(
    (acc, x) => {
    
    
      if (keyBy(x) > keyBy(acc[0])) {
    
    
        return [x];
      }
      if (keyBy(x) === keyBy(acc[0])) {
    
    
        return [...acc, x];
      }
      return acc;
    },
    [list[0]],
  );
};

const data = [{
    
     value: 6 }, {
    
     value: 6 }, {
    
     value: 4 }];
 
//=> { value: 6 }
console.log(maxBy(data, (x) => x.value));

七. 统计字符串中出现次数最多的字符及次数

//=> ['a', 6]
getFrequentChar("aaabbaaacc");
 
//=> ['a', 3]
getFrequentChar("aaa");
function getFrequentChar(str) {
    
    
  const dict = {
    
    };
  for (const char of str) {
    
    
    dict[char] = (dict[char] || 0) + 1;
  }
  const maxBy = (list, keyBy) =>
    list.reduce((x, y) => (keyBy(x) > keyBy(y) ? x : y));
  return maxBy(Object.entries(dict), (x) => x[1]);
}

八. 手写实现Reduce

Array.prototype.reduce = function reduce(fun, init) {
    
    
  const length = this.length;
  let result;
  let start;
  if (typeof fun !== "function") {
    
    
    throw new TypeError("is not fun");
  }
  if (length === 0 && init === undefined) {
    
    
    throw new TypeError("");
  }
  if (init !== undefined) {
    
    
    result = init;
    start = 0;
  } else {
    
    
    for (let i = 0; i < length; i++) {
    
    
      if (this.hasOwnProperty(i)) {
    
    
        result = this[i];
        start = i + 1;
        break;
      }
    }
    if (start === undefined) {
    
    
      throw new TypeError("");
    }
  }
 
  for (let i = start; i < length; i++) {
    
    
    if (this.hasOwnProperty(i)) {
    
    
      result = fun(result, this[i], i, this);
    }
  }
  return result;
};

let arr = [1, 2, 3, 4]
let sum = arr.reduce((pre, cur) => {
    
    
  return pre += cur
}, 0)
console.log(sum);

猜你喜欢

转载自blog.csdn.net/qq_63299825/article/details/135954518