Es ist tatsächlich möglich. Wenn die Funktion entweder mit function
Syntax oder Function
Konstruktor erstellt wird, erhält es interne [[Call]]
Eigenschaft. Es ist keine Eigenschaft der Funktion selbst, sondern eine Eigenschaft, die jede Funktion erhält, wenn sie konstruiert wird.
Während das nur bedeutet, dass irgendetwas mit [[Call]]
könnte nur Function
wenn es gebaut ist (na ja, mit einer Ausnahme nicht – Function.prototype
selbst, die nicht von Function
erbt), dass es etwas anderes bedeutet nicht, nicht später werden kann, unter Beibehaltung [[Call]]
Eigentum. Nun, vorausgesetzt, Ihr Browser ist kein IE
Die Sache, die erlaubt, die Magie zu ändern wäre __proto__
von ES6, bereits in vielen Browsern implementiert. __proto__
ist eine magische Eigenschaft, die aktuellen Prototyp enthält. Indem ich es ändere, kann ich eine Funktion erstellen, die von etwas erbt, das nicht Function
ist.
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)
Zuerst wird der Konstruktor für CallablePoint
macht ein Function
(nur Function
s sind erlaubt mit [[Call]]
Eigentum beginnen. Als nächstes ich ihr Vorbild zu ändern, so wäre es CallablePoint
zu erben. An dieser Stelle habe ich eine Funktion, die doesn ‚t von Function
(Art von verwirrenden) erben.
Nachdem I definiert Konstruktor für CallablePoint
s, habe ich den Prototyp zu CallablePoint
Function
, so habe ich CallablePoint
, die von Function
erbt.
Auf diese Weise haben die CallablePoint
Instanzen Prototyp-Kette: CallablePoint -> Function -> Object
, während noch aufrufbar sein. Da das Objekt auch aufrufbar ist, hat es gemäß der Spezifikation typeof
gleich 'function'
.
Sie wissen, dass 'function point() {return point}' würde nur die Funktion selbst zurückgeben? Was hast du damit vor? Es würde Ihnen erlauben, 'p()()()()()()()()()' aber was ist der Punkt? (kein Wortspiel beabsichtigt). –
@FelixKling Ich musste mich verständlicherweise von der Beantwortung dieser Frage verabschieden – Pointy
Der Vollständigkeit halber hat ES6 eine bessere Lösung dafür, siehe: http://stackoverflow.com/questions/36871299/how-to-e-tend-function-with -es6-classes – 0xc0de