2016-12-05 52 views
3

所以,我寫了一些示例代碼實現Constructor[Symbol.hasInstance]的另一個函數,我注意到我的新實現不會被調用。重新實現的構造函數[Symbol.hasInstance]但它仍然不會被調用

下面的腳本是什麼,我希望發生:

function Pirate(name) { 
    this.name = name; 
} 

const jackSparrow = { 
    isPirate: true 
}; 

// Notice how `jackSparrow` is not yet considered an instance of the `Pirate` object 
console.log(jackSparrow instanceof Pirate); // false 

// Now let's assign another function for `Pirate[Symbol.hasInstance]` 
Pirate[Symbol.hasInstance] = function (anObj) { 
    return anObj.isPirate; 
}; 

// This will cause Pirate[Symbol.hasInstance] to be called with `jackSparrow` 
console.log(jackSparrow instanceof Pirate); // true 

,我打算給console.log調用添加到我的海盜[Symbol.hasInstance]實現,但它不會記錄任何的安慰。

有沒有人有任何想法發生了什麼?爲什麼我的實現不被調用?

我在節點6.9.1上運行這個。

回答

6

你可以找到答案,如果你做

Object.getOwnPropertyDescriptor(Function.prototype, Symbol.hasInstance).writable 

它返回false:你不能寫一個函數與賦值操作符=Symbol.hasInstance財產。該屬性永遠不會被設置,所以它永遠不會被調用。 (如果你處於嚴格模式,你應該一直使用它的許多原因之一,那麼TypeError就會引發一條有用的消息,引發財產與Object.defineProperty功能。

Object.defineProperty(Pirate, Symbol.hasInstance, { 
    value: function(anObj) { 
     console.log('Is he a pirate?'); 
     return anObj.isPirate; 
    } 
}); 

現在jackSparrow instanceof Pirate第一次登錄的問題,然後返回true

+0

...或使用'class'定義了'靜態[Symbol.hasInstance ](obj){...}'方法 – Bergi

2

@lonesomeday's answer解釋原因。如果對象已將該屬性繼承爲不可寫,則分配不會定義屬性。

如果你不想使用明確的屬性定義,可以考慮使用類語法:

class Pirate { 
 
    constructor(name) { 
 
    this.name = name; 
 
    } 
 
    static [Symbol.hasInstance](anObj) { 
 
    return anObj.isPirate; 
 
    } 
 
} 
 
const jackSparrow = { 
 
    isPirate: true 
 
}; 
 
console.log(jackSparrow instanceof Pirate); // true

+0

這是ES6的好答案,絕對是! – lonesomeday

+0

我不是ES6課程的忠實粉絲,但是非常感謝! – lucasfcosta

相關問題