likes
comments
collection
share

每日前端手写题--day1

作者站长头像
站长
· 阅读数 9

第一天要刷的手写题如下:

  1. 手写一个函数,实现new操作符。
  2. 手写一个函数,实现Object.create方法。
  3. 手写一个函数,实现instanceof操作符。

下面是我自己写的答案:

1. 手写一个函数,实现new操作符

根据new操作符的作用原理,可以比较方便的写出其实现:

new执行以下几个步骤:
1.  创建一个空对象:new操作符会创建一个新的空对象,该对象继承自构造函数的原型对象。
2.  设置对象的原型链:新创建的空对象的__proto__属性会被设置为构造函数的prototype属性,这样就建立了对象与构造函数原型之间的连接。
3.  执行构造函数代码:将新创建的空对象作为this关键字绑定到构造函数,并执行构造函数内部的代码。这样,构造函数可以通过this来操作和设置新对象的属性和方法。
4.  返回新对象实例:如果构造函数没有显式返回值,则new操作符会隐式返回新创建的对象实例。如果构造函数有返回值,有以下两种情况:
    -   如果返回值是一个对象,则new操作符会返回该对象。
    -   如果返回值不是一个对象(比如基本数据类型),则忽略返回值,返回新创建的对象。

自己实现的myNew函数,接受一个function类型的参数作为其"类",接受剩余参数作为返回对象的初始化值。

function myNew (constructor, ...rest) {
    // 判断传入的参数是否有效
    if(typeof constructor !== "function") throw new Error("参数一必须是构造函数");
    // 绑定原型
    const obj = Object.create(constructor.prototype);
    // 执行构造函数
    const rst = constructor.apply(obj, rest);
    return (rst && (typeof rst === "object")) ? rst : obj;
}

2. 手写一个函数,实现Object.create方法

Object.create方法的作用为:

Object.create()方法是JavaScript中用于创建一个新对象的方法。它的作用是以指定的原型对象作为新对象的原型,并可选择性地为新对象定义属性和方法。
Object.create(proto, [propertiesObject])接受两个参数:
1.  proto:必需,表示新对象的原型。它可以是一个对象字面量、null或者其他已存在的对象。新对象将继承proto对象的属性和方法。
2.  propertiesObject(可选):一个可选的对象,用于定义新对象的属性和方法。该对象的每个属性都是通过属性描述符来定义的,类似于Object.defineProperty()的第二个参数。

借用原型设计模式实现Object.create:

function myCreate(proto, propertiesObject) {
  if (Object(proto) !== proto) {
    throw new TypeError('Object prototype may only be an Object or null');
  }
  // 创建一个空函数
  function F() {}
  // 指定此函数的原型
  F.prototype = proto;
  // 创建待返回实例
  const obj = new F();
  // 往实例对象上添加属性
  if (propertiesObject !== undefined) {
    Object.defineProperties(obj, propertiesObject);
  }
  // 返回实例对象
  return obj;
}

3. 手写一个函数实现instanceof操作符的功能

  • x instanceof y 的作用原理就是,在x的原型链上寻找y,如果找到了就返回true,如果找不到就返回false;
  • 根据其作用原理,其实现过程也就呼之欲出了:首先判断x是不是object类型的,如果不是直接返回false就可以了。如果是的话,则逐级比较x的原型和y是否相等,知道x原型链的尽头,也就是null。如果此时y与任何一层原型都不相等,则返回false,否则返回true。
  • 实现代码如下:
function myInstanceof(obj, cons){
    if(Object(obj)!==obj) return false;
    let _p = obj.__proto__;
    while(_p!==null){
      if(_p==cons.prototype) return true;
      _p = _p.__proto__;
    }
    return false;
}