每日一题 -- 手撕代码面试题

106 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第11天,点击查看活动详情

🧑🏿‍💻 今天不想写力扣题了,连续坚持了一个多月了吧,有点累了。今天想看一些手撕代码题,找点简单的,找回一点自信心,感觉参加了两周的力扣周赛之后都有点泄气了,提不起精神来了。哎,主要是看那些力扣上的那些大神半小时内做完四题,然后自己一个小时两题都很勉强,真的被打击到了。 所以今天做点别的了,找了三道相对简单的面试可以会到的手撕代码题。

1. 手写Object.create方法的实现

要写出来首先需要知道Object.create是干什么用的。 Object.create() 方法用于创建一个新对象,使用现有的对象来作为新创建对象的原型(prototype)。

直接根据上面给出的Object.create的定义就可以写出来

function objectCreate (obj) {
  function newObj() {} // 创建一个新的构造函数
  newObj.prototype = obj
  return new newObj()
}

let person = {
  name: 'obj',
  age: 16
}
let newPerson = objectCreate(person)
console.log(newPerson)

2. 实现instanceof 方法

🧑🏿‍💻 instanceof 只能判断引用类型。而且他的原理就是在原型链上查找。如果找到就返回true, 如果找不到就继续往原型链向下查找,知道找的原型属性为空,还没找到就返回false
function instanceofFunc (left, right) {
  let proto = Object.getPrototypeOf(left)
  while (proto) {
    if (proto === right.prototype) {
      return true
    } else {
      proto = Object.getPrototypeOf(proto)
    }
  }
  return false
}
let arr = [12,3]
console.log(instanceofFunc(arr, Array))

实现instanceof: left是一个对象变量,直接使用left.prototype是无法获取原型链的。获取对象原型的方法推荐使用: Object.getPrototypeOf() right是一个构造函数,可以直接使用right.prototype 获取到原型。而 right 只是一个函数,无法直接与原型做比较


3. new操作符的实现

🧑🏿‍💻 new 运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例。
/**
 * 当代码 new Foo(...) 执行时,会发生以下事情:

1. 一个继承自 Foo.prototype 的新对象被创建。
2. 使用指定的参数调用构造函数 Foo,并将 this 绑定到新创建的对象。new Foo 等同于 new Foo(),也就是没有指定参数列表,Foo 不带任何参数调用的情况。
3. 由构造函数返回的对象就是 new 表达式的结果。
如果构造函数没有显式返回一个对象,则使用步骤 1 创建的对象。(一般情况下,构造函数不返回值,但是用户可以选择主动返回对象,来覆盖正常的对象创建步骤)
 */
new 关键字会进行如下的操作:

    1. 创建一个空的简单 JavaScript 对象(即 {});
    2. 为步骤 1 新创建的对象添加属性 __proto__,将该属性链接至构造函数的原型对象;
    3. 将步骤 1 新创建的对象作为 this 的上下文;
    4. 如果该函数没有返回对象,则返回 this。
// apply() 方法调用一个具有给定 this 值的函数,以及以一个数组(或一个类数组对象)的形式提供的参数。
function newFn (fn, params) {
  let obj = {}
  if (typeof fn !== 'function') {
    return
  }
  // 基于fn的原型创建一个新的对象
  obj = Object.create(fn.prototype)
  // 添加属性到新创建的obj上, 并获取fn函数的执行结果
  let result = fn.apply(obj, params)
  // 判断返回对象
  let flag = result && (typeof result === 'object' || typeof result === 'function')
  // 如果执行结果有返回值并且是一个对象, 返回result, 否则返回新创建的对象
  return flag ? result : obj
}
let fn = function () {
  return {
    a: 1,
    b: 2
  }
}
console.log(newFn(fn))