date = new Date()
let array = []
let obj = {} // 字面量是直接生成构造函数的
console.log(newNumber instanceof Number) // true
console.log(newString instanceof String) // true
console.log(newBoolean instanceof Boolean) // true
console.log(Fn instanceof Function) // true
console.log(date instanceof Date) // true
console.log(array instanceof Array) // true
console.log(obj instanceof Object) // true
// 判断是否为数组,建议使用 isArray()
console.log(Array.isArray(array)) // true
小测试,检验一下:
function Fn() {}
let obj = new Fn()
console.log(obj instanceof Function) // false
console.log(obj instanceof Object) // true
console.log(Fn instanceof Function) // true
obj 是构造函数 new 出来的实例对象,所以 obj 的原型链上应该是Object。
2-5.原理
思路: 比较左边 object 的proto 是否存在于 右边 constructor 的原型链上, 左边 object 查找到 null 位置。 手撕代码如下:
/**
* ES5 ES6 模拟instanceof
* @author 阿吉
* @param {Object} object
* @param {Object} constructor
*/
function myInstanceofES5(object, constructor) {
var Prototype = constructor.prototype // constructor 的显式原型
object = object.__proto__ // object 的隐式原型
while (true) {
if (object === null) return false
if (object === Prototype) return true
object = object.__proto__
const myInstanceofES6 = (object, constructor) =>
object == null
? false
: object == constructor
? true
: myInstanceof(myInstanceof.__proto__, constructor)
既然typeof用来检测 基本数据类型,instanceof用来检测引用数据类型,那么有没有一种方法,既能检测基本数据类型,又能检测引用数据类型呢?答案就是Object.prototype.toString.call(val)或Reflect.apply(Object.prototype.toString,val,[])。它可以确定任何对象的特定类型。
2-6. instanceof 应用
手撕 bind 检测是否使用 new 创建 class