有两个代码片段显示了我遇到的问题。
demo1.js:
// using ES6+ class syntax
class MyObject {
constructor() {
this.myProp1 = 'myProp1';
}
get [Symbol.toStringTag]() {
console.log('[Custom Symbol.toStringTag]]');
return 'CustomTag';
}
static [Symbol.hasInstance](instance) {
console.log('[Custom Symbol.hasInstance]');
return false;
}
}
const myObj = new MyObject();
console.log(Object.prototype.toString.call(myObj)); // works correctly, implicitly called custom getter Symbol.toStringTag
// first log print [Custom Symbol.toStringTag]], then log print [object CustomTag], since custom getter Symbol.toStringTag return 'CustomTag'
console.log(myObj instanceof MyObject); // works correctly, implicitly called custom static method Symbol.hasInstance
// first log print [Custom Symbol.hasInstance], then log print false, since custom static method Symbol.hasInstance return false
demo2.js:
// using classic prototype syntax
function MyObject() {
this.myProp1 = 'myProp1';
}
Object.defineProperty(MyObject.prototype, Symbol.toStringTag, {
configurable: true,
enumerable: true,
get() {
console.log('[Custom Symbol.toStringTag]]');
return 'CustomTag';
}
})
// is this a correct way to define a static method to MyObject by using classic prototype syntax?
MyObject[Symbol.hasInstance] = function (instance) {
console.log('[Custom Symbol.hasInstance]');
return false;
}
const myObj = new MyObject();
console.log(Object.prototype.toString.call(myObj)); // works correctly, implicitly called custom getter Symbol.toStringTag
// first log print [Custom Symbol.toStringTag]], then log print [object CustomTag], since custom getter Symbol.toStringTag return 'CustomTag'
console.log(myObj instanceof MyObject); // does not works correctly, does not implicitly called custom static method Symbol.hasInstance
// just log print true
我的问题:
MyObject[Symbol.hasInstance] = function (instance) { ... }
是使用经典原型语法定义静态方法的正确方法吗?MyObject[Symbol.hasInstance] = function (instance) { ... }
是定义静态方法的正确方法,为什么js运算符instanceof
不隐式调用自定义静态方法Symbol.hasInstance?btw,关于大家熟知的Symbol Symbol.hasInstance,请参考MDN网页
代码中的问题是您无法通过简单的赋值覆盖函数的
Symbol.hasInstance
。以下是一些评价:
function f(v) {
return v === 3;
}
const A = {
[Symbol.hasInstance]: f
}
console.log("2 instanceof A:", 2 instanceof A);
console.log("3 instanceof A:", 3 instanceof A);
console.log("A[Symbol.hasInstance] === f:", A[Symbol.hasInstance] === f);
const B = {};
B[Symbol.hasInstance] = f;
console.log("2 instanceof B:", 2 instanceof B);
console.log("3 instanceof B:", 3 instanceof B);
console.log("B[Symbol.hasInstance] === f:", B[Symbol.hasInstance] === f);
function C() {}
C[Symbol.hasInstance] = f;
console.log("2 instanceof C:", 2 instanceof C);
console.log("3 instanceof C:", 3 instanceof C);
console.log("C[Symbol.hasInstance] === f:", C[Symbol.hasInstance] === f);
它适用于常见的静态方法。为了达到预期的结果,您可以使用
Object.defineProperty
。