返回

源码实现:大厂面试必知

前端

作为一名技术面试官,我经常被问到一些看似简单的编码问题,但它们往往能揭示候选人的基础知识和解决问题的能力。这些问题通常与JavaScript中的核心概念有关,例如函数、对象和继承。

为了帮助您在下一场技术面试中脱颖而出,我整理了一份大厂面试中经常出现的源码实现问题清单:

call、apply 和 bind 函数的实现

这三个函数都是函数调用的变体,允许您更改函数的上下文(this )。

  • call 接受一个参数列表,其中第一个参数是 this 的值,其余参数是传递给函数的参数。
  • applycall 类似,但它接受一个数组作为第二个参数,其中包含要传递给函数的参数。
  • bind 创建一个新的函数,该函数的 this 值绑定到指定的上下文,并且可以稍后使用不同的参数调用。

Object.assign 的实现

Object.assign 函数用于将一个或多个源对象的属性复制到目标对象。

Object.assign = function(target, ...sources) {
  for (const source of sources) {
    for (const key in source) {
      if (source.hasOwnProperty(key)) {
        target[key] = source[key];
      }
    }
  }
  return target;
};

Object.create 的实现

Object.create 函数创建一个新对象,该对象具有指定的原型对象。

Object.create = function(proto, propertiesObject) {
  if (typeof proto !== 'object' && typeof proto !== 'function') {
    throw new TypeError('Object prototype may only be an Object or a Function');
  }

  function F() {}
  F.prototype = proto;
  const obj = new F();

  if (propertiesObject) {
    Object.defineProperties(obj, propertiesObject);
  }

  return obj;
};

new 操作符的实现

new 操作符创建一个新对象,并将其原型设置为构造函数的原型。

function _new(constructor, ...args) {
  const obj = Object.create(constructor.prototype);
  const result = constructor.apply(obj, args);
  return typeof result === 'object' ? result : obj;
}

instanceof 操作符的实现

instanceof 操作符检查一个对象是否属于一个类。

function _instanceof(obj, constructor) {
  let proto = obj.__proto__;
  while (proto) {
    if (proto === constructor.prototype) {
      return true;
    }
    proto = proto.__proto__;
  }
  return false;
}

继承方式

原型链继承

在原型链继承中,子类通过其原型链继承父类的属性和方法。

class Parent {
  constructor(name) {
    this.name = name;
  }
}

class Child extends Parent {}

const child = new Child('John');
child.name; // 'John'

借用构造函数继承

在借用构造函数继承中,子类调用父类的构造函数来初始化其实例。

class Parent {
  constructor(name) {
    this.name = name;
  }
}

class Child {
  constructor(name, age) {
    Parent.call(this, name);
    this.age = age;
  }
}

const child = new Child('John', 30);
child.name; // 'John'
child.age; // 30

组合继承

组合继承结合了原型链继承和借用构造函数继承。

class Parent {
  constructor(name) {
    this.name = name;
  }
}

class Child {
  constructor(name, age) {
    Parent.call(this, name);
    this.age = age;
  }

  getName() {
    return this.name;
  }
}

Object.setPrototypeOf(Child.prototype, Parent.prototype);

const child = new Child('John', 30);
child.getName(); // 'John'

希望这份清单能帮助您为下一场技术面试做好准备。请记住,练习是提高编码技能的关键。通过定期练习这些实现,您将能够自信地回答这些问题,并向面试官展示您扎实的JavaScript基础知识。