Resulta que en realidad es posible. Cuando se crea la función, ya sea utilizando la sintaxis function
o el constructor Function
, obtiene la propiedad interna [[Call]]
. No es una propiedad de la función en sí misma, sino propiedad que cualquier función obtiene cuando se construye.
Mientras que sólo significa que cualquier cosa con [[Call]]
podría ser solamente Function
cuando se construyó (bueno, hay una excepción – Function.prototype
sí que no hereda de Function
), eso no quiere decir que no puede convertirse en algo más tarde, preservando la propiedad [[Call]]
. Bueno, siempre que su navegador no sea IE < 11.
Lo que permite cambiar la magia sería __proto__
de ES6, ya implementado en muchos navegadores. __proto__
es una propiedad mágica que contiene el prototipo actual. Al cambiarlo, puedo hacer que la función herede de algo que no es 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)
En primer lugar, el constructor de CallablePoint
hace un Function
(sólo Function
s se les permite comenzar con [[Call]]
propiedad. A continuación, cambie su prototipo, por lo que heredarían CallablePoint
. En este punto, tengo una función que doesn 't heredan de Function
(especie de confuso).
Después he definido constructor para CallablePoint
s, he de poner el prototipo de CallablePoint
a Function
, así que tengo CallablePoint
que hereda de Function
.
De esta forma, las instancias CallablePoint
tienen una cadena de prototipo: CallablePoint -> Function -> Object
, aunque siguen siendo invocables. Además, como el objeto es invocable, tiene según la especificación typeof
igual a 'function'
.
Usted sabe que 'punto de función() {}' punto de retorno sólo devuelve la función en sí? ¿Qué piensas con esto? Te permitiría hacer 'p()()()()()()()()()' pero ¿cuál es el punto? (sin juego de palabras) –
@FelixKling comprensiblemente tuve que recusarme de contestar esta pregunta – Pointy
Para mayor información, ES6 tiene una mejor solución para esto, vea: http://stackoverflow.com/questions/36871299/how-to-extend-function-with -es6-classes – 0xc0de