それは実際に可能であることが判明しました。function
構文またはコンストラクターを使用して関数を作成すると、Function
内部[[Call]]
プロパティを取得します。これは関数自体のプロパティではなく、関数が構築されたときに取得するプロパティです。
[[Call]]
それは、それが構築されたときにのみ存在する可能性があることを意味しFunction
ますが(1つの例外があります-Function.prototype
それ自体はから継承されません)、それはプロパティFunction
を保持しながら後で何かになることができないことを意味しません。[[Call]]
ええと、あなたのブラウザがIE<11でなければ。
魔法を変えることができるのは__proto__
、すでに多くのブラウザに実装されているES6からのものです。__proto__
現在のプロトタイプを含む魔法のプロパティです。変更することで、そうでないものから継承する機能を作ることができFunction
ます。
function CallablePoint(x, y) {
function point() {
// Complex calculations at this point
return point
}
point.__proto__ = CallablePoint.prototype
point.x = x
point.y = y
return point
}
// CallablePoint should inherit from Function, just so you could use
// various function methods. This is not a requirement, but it's
// useful.
CallablePoint.prototype = Object.create(Function.prototype)
CallablePoint
まず、 makesのコンストラクターFunction
(Function
sのみがプロパティで開始でき[[Call]]
ます。次に、プロトタイプを変更して継承しCallablePoint
ます。この時点で、継承しない関数がありFunction
ます(混乱を招きます)。
sのコンストラクターを定義した後CallablePoint
、のプロトタイプをに設定したCallablePoint
のでFunction
、CallablePoint
から継承しFunction
ます。
このように、CallablePoint
インスタンスにはプロトタイプチェーンがあります:CallablePoint -> Function -> Object
、まだ呼び出し可能です。また、オブジェクトは呼び出し可能であるため、仕様に従って、にtypeof
等しくなり'function'
ます。