type of

typeof 操作符最适合用来判断一个变量是否为原始类型,更确切地说,它是判断一个变量是否为字符串、数值、布尔值或 undefined 的最好方式,如果值是对象或 null ,那么 typeof 返回 “object”

  1. let s = "Nicholas";
  2. let b = true;
  3. let i = 22;
  4. let u;
  5. let n = null;
  6. let o = new Object();
  7. console.log(typeof s); // string
  8. console.log(typeof i); // number
  9. console.log(typeof b); // boolean
  10. console.log(typeof u); // undefined
  11. console.log(typeof n); // object
  12. console.log(typeof o); // object

instanceof

instanceof 用来判断引用数据类型,,返回ture 或 false
instanceof 运算符可以用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上
如果用 instanceof 检测原始值,则始终会返回 false ,因为原始值不是对象

  1. // object 某个实例对象
  2. // constructor 某个构造函数
  3. result = variable instanceof constructor

那我们就可以理解为:instanceof 运算符用来检测 constructor.prototype 是否存在于参数 obejct 的原型链上

  1. // 定义构造函数
  2. function C(){}
  3. function D(){}
  4. var o = new C();
  5. o instanceof C; // true
  6. o instanceof D; // false
  7. o instanceof Object; // true

具体判断

  1. console.log(person instanceof Object); // 变量 person 是 Object 吗?
  2. console.log(colors instanceof Array); // 变量 colors 是 Array 吗?
  3. console.log(pattern instanceof RegExp); // 变量 pattern 是 RegExp 吗?

那么实现原理是什么呢?
instanceof 的内部实现机制是:通过判断参数对象的原型链上是否能找到构造函数的 prototype,来确定 instanceof 的返回值。
我们可以使用 Object.getPrototypeOf(obj) 来判断是否等于构造函数的 prototype;也可以使用 Object.prototype.isPrototypeOf(obj) 返回值来判断,比如上述例子:

  1. o instanceof C; // true
  2. // Object.getPrototypeOf(o) === C.prototype
  3. o instanceof Object; // true
  4. // Object.prototype.isPrototypeOf(o) 返回 true

当然我们也可以使用其他方法来实现:

  1. function instance_of(obj, cons) {
  2. var consPrototype = cons.prototype;
  3. var objProrotype = obj.__proto__;
  4. while(true) {
  5. if (objProrotype === null) {
  6. return false;
  7. }
  8. if (consPrototype === objProrotype) {
  9. return true
  10. }
  11. // 原型链向上查找
  12. objProrotype = objProrotype.__proto__;
  13. }
  14. }

怎么去实现一个 instanceof 的功能呢?
那根据上述所讲,我们自己去实现一个 instanceof 方法,有三种方式:

  1. Object.getPrototypeOf(obj)——返回指定对象的原型(内部 [[Prototype]] 属性的值)
  2. Object.prototype.isPrototypeOf(obj)——测试一个对象是否存在于另一个对象的原型上
  3. obj.proto——使用非标准的 proto 的伪属性

源码实现
1. 使用 Object.getPrototypeOf(obj)

  1. function instance_of(o, c) {
  2. let op = Object.getPrototypeOf(o);
  3. const cp = c.prototype;
  4. while(true) {
  5. if (!op) {
  6. return false
  7. }
  8. if (op === cp) {
  9. return true
  10. }
  11. op = Object.getPrototypeOf(op);
  12. }
  13. }
  1. Object.prototype.isPrototypeOf(obj)
    1. function instance_of(o, c) {
    2. return c.prototype.isPrototypeOf(o);
    3. }
  2. obj.proto

    1. function instance_of(o, c) {
    2. let op = o.__proto__;
    3. const cp = c.prototype;
    4. while(true) {
    5. if (op === null) {
    6. return false
    7. }
    8. if (op === cp) {
    9. return true
    10. }
    11. op = op.__proto__;
    12. }
    13. }