instanceof 检测原理

instanceof:检测原理 

+ 检测某个实例是否属于这个类的
+ 基于instanceof可以细分一下不同类型的对象「也可以检测出基于构造函数方式创建出来的基本类型对象值」   
+ 临时当“壮丁”的,存在很多问题
        + 原理:构造函数 Symbol.hasInstance 属性方法 (实例)
        + 原理:检测当前构造函数的原型prototype是否出现在,当前实例所处的原型链上__proto__,如果能出现结果就是true
        + 在JS中原型链是可以改动的,所有结果不准确
        + 所有实例的原型链最后都指向Object.prototype,所以 “实例 instacnceof Object”的结果都是true
        + 字面量方式创造的基本数据类型值是无法基于 instanceof 检测的「浏览器默认并不会把它转换为new的方式」,所以它本身不是对象,不存在__proto__这个东西
        + 「自己的方法想把基本数据类型也处理了」
        + ...

function instance_of(example, classFunc) {
  // 参数初始化
  if (typeof classFunc !== "function") throw new TypeError("Right-hand side of 'instanceof' is not callable");
  if (example == null) return false;
  // 支持Symbol的并且拥有Symbol.hasInstance,以这个处理
  if (typeof Symbol !== "undefined") {
    var hasInstance = classFunc[Symbol.hasInstance];
    console.log(hasInstance, typeof hasInstance === "function", 'hasInstance')
    if (typeof hasInstance === "function") {
      return hasInstance.call(classFunc, example);
    }
  }
  // 不支持的则基于检测原型链来实现
  var prototype = classFunc.prototype,
    proto = Object.getPrototypeOf(example);
  if (!prototype) return false; // 没有prototype的函数(例如:箭头函数)直接返回false
  while (true) {
    // 找到Object.prototype.__proto__
    if (proto === null) return false;
    // 在原型链上找到了类的原型
    if (proto === prototype) return true;
    proto = Object.getPrototypeOf(proto);
  }
}
let res = instance_of([12, 23], Array);
console.log(res); //=>true  

res = instance_of([12, 23], Object);
console.log(res); //=>true  

res = instance_of([12, 23], RegExp);
console.log(res); //=>false  

res = instance_of(1, Number);
console.log(res); //=> 支持Symbol的情况 false 不支持Symbol的情况 true

你可能感兴趣的:(JavaScript,面试,javascript,instanceof,检测原理)