Skip to content

手写代码

手写 instanceof

相关知识:JavaScript-数据类型-数据类型检测

ts
export function instanceOf(obj: unknown, constructor: any): boolean {
  // 获取对象的 prototype 属性
  let proto = Object.getPrototypeOf(obj);
  // 获取构造函数的 prototype 属性
  const prototype = constructor.prototype;
  // 遍历对象的原型链
  while (true) {
    // 原型链遍历结束,未找到相同的 prototype 属性
    if (proto === null) return false;
    // 找到了相同的 prototype 属性
    if (proto === prototype) return true;
    // 未找到且未结束,继续遍历
    proto = Object.getPrototypeOf(proto);
  }
}
mdx
// 使用示例
import { instanceOf } from 'sth';

instanceOf([], Array); // true
instanceOf({}, Object); // true

// 原生 instanceof 无法正确判断原始数据类型的类型
2 instanceof Number; // false

// instanceOf 可以正确判断原始数据类型的类型
instanceOf(2, Number); // true

手写 typeof

相关知识:JavaScript-数据类型-数据类型检测

ts
import { DataType } from '../types';

export function typeOf(obj: unknown): DataType {
  // 判断 Null
  if (obj === null) return 'null';
  if (typeof obj === 'object') {
    // 引用数据类型,使用 Object.prototype.toString.call 判断
    return Object.prototype.toString.call(obj).slice(8, -1).toLowerCase();
  } else {
    // 原始数据类型,使用 typeof 判断
    return typeof obj;
  }
}
mdx
// 使用示例
import { typeOf } from 'sth';

typeOf(2); // number
typeOf(true); // boolean

// 原生 typeof 无法正确判断引用数据类型的类型
typeof []; // object
typeof null; // object
typeof /a/; // object

// typeOf 可以正确判断引用数据类型的类型
typeOf([]); // array
typeOf(null); // null
typeOf(/a/); // regexp

手写 new

相关知识:JavaScript-函数-new

ts
export function New(...argv: any): object | Function {
  const constructor: unknown = Array.prototype.shift.call(arguments);
  if (typeof constructor !== 'function') {
    throw new Error(`Uncaught TypeError: constructor should be a function`);
  }
  // 创建一个原型为构造函数的新对象
  const obj = Object.create(constructor.prototype);
  // 执行构造函数,并将 this 指向对象
  const res = constructor.apply(obj, arguments);
  // 执行结果是引用类型,则返回执行结果;是值类型,则返回创建的对象
  if (res !== null && (typeof res === 'object' || typeof res === 'function')) {
    return res;
  } else {
    return obj;
  }
}
mdx
import { New } from 'sth';

function Person(name: string, age: number) {
  this.name = name;
  this.age = age;
  this.introduce = function (): string {
    return 'My name is ' + this.name + ', ' + this.age + ' years old.';
  };
}

const person: any = New(Person, 'Li Lei', 18);
person.name ; // 'Li Lei'
person.age; //18
person.introduce(); // 'My name is Li Lei, 18 years old.'

function PlainObject(a: any) {
  this.b = 2;
  return {
    a,
  };
}

const object: any = New(PlainObject, 1);
object.a; // 1

function IntNumber(a: number) {
  this.b = 2;
  return a;
}

const number = new IntNumber(1);
number; // { b: 2 }