Symbol.hasInstance 用法

简介

对象的 Symbol.hasInstance 属性,指向一个内部方法。当其他对象使用 instanceof 运算符,判断是否为该对象的实例时,会调用这个方法。比如,foo instanceof Foo 在语言内部,实际调用的是 Foo[Symbol.hasInstance](foo)。详解见 阮一峰的ES6教程

检验

基于上述内容我做了一个检验,在多个内置函数中均找到了 Symbol.hasInstance 方法,比如 ArrayStringObjectBooleanNumber 等。

Array[Symbol.hasInstance] // ƒ [Symbol.hasInstance]() { [native code] }
String[Symbol.hasInstance] // ƒ [Symbol.hasInstance]() { [native code] }
Object[Symbol.hasInstance] // ƒ [Symbol.hasInstance]() { [native code] }
Boolean[Symbol.hasInstance] // ƒ [Symbol.hasInstance]() { [native code] }
Number[Symbol.hasInstance] // ƒ [Symbol.hasInstance]() { [native code] }

并且这些方法都是同一个方法:

Array[Symbol.hasInstance]  === String[Symbol.hasInstance] // true
String[Symbol.hasInstance] === Object[Symbol.hasInstance] // true
Object[Symbol.hasInstance] === Boolean[Symbol.hasInstance] // true
Boolean[Symbol.hasInstance] === Number[Symbol.hasInstance] // true

猜想: 这些方法可能都来自于原型链上,因为上述函数都是Function的实例,于是找到上级的原型 Function.prototype,果不其然。

Function.prototype.hasOwnProperty(Symbol.hasInstance) // true

用法

借用 阮一峰 老师写的例子:

class Even {
  static [Symbol.hasInstance](obj) {
    return Number(obj) % 2 === 0;
  }
}

// 等同于
const Even = {
  [Symbol.hasInstance](obj) {
    return Number(obj) % 2 === 0;
  }
};

1 instanceof Even // false
2 instanceof Even // true
12345 instanceof Even // false

是不是很酷,可以直接自定义 instanceof 的用法,于是我突发奇想,实现一个通过 instanceof 判断是不是 基本数据 类型的例子,如下:

class BasicType {
    static [Symbol.hasInstance](data) {
        // 把 除了null以外的所有基本数据类型放到一个数组里
        const basics = ['string', 'number', 'boolean', 'undefined',  'symbol', 'bigint']
        // 判断 typeof 之后的结果是否在这个数组中,或者 data 是否为 null
        // 因为typeof null为'object',所以这里特殊判断一下
        return basics.includes(typeof data) || data === null
    }
}

基本数据类型验证

1 instanceof BasicType // true
'abc' instanceof BasicType // true
true instanceof BasicType // true
Symbol() instanceof BasicType // true
123n instanceof BasicType // true
undefined instanceof BasicType // true
null instanceof BasicType // true

引用数据类型验证

// 对象
({}) instanceof BasicType // false
// 数组
[] instanceof BasicType // false
// 函数
Array instanceof BasicType // false
// set 
new Set() instanceof BasicType // false
// map
new Map() instanceof BasicType // false

END,感谢阅读!欢迎评论区留言讨论~

上一篇: vue2 直接更改路由的query参数
下一篇: Symbol.isConcatSpreadable 用法

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容