事实证明这实际上是可能的。当函数被创建时,无论是使用function
语法还是Function
构造函数,它都会获得内部[[Call]]
属性。它不是函数本身的属性,而是任何函数在构造时获得的属性。
虽然这仅意味着任何 with[[Call]]
只能Function
在它被构造时才存在(嗯,有一个例外——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
make a Function
(只Function
允许 s 以[[Call]]
属性开头。接下来,我更改了它的原型,所以它会继承CallablePoint
。此时我有一个不继承自的函数Function
(有点令人困惑)。
在我为 s 定义了构造函数之后CallablePoint
,我将原型设置CallablePoint
为Function
,所以我CallablePoint
继承了Function
。
这样,CallablePoint
实例具有原型链:CallablePoint -> Function -> Object
,同时仍然可以调用。此外,由于该对象是可调用的,因此根据规范,它typeof
等于'function'
.