在JavaScript中,函数是可调用的。
我可以从函数中删除此属性,只留下普通对象吗?
var foo = function () {};
foo.[[callable]] = false; // pseudocode
foo(); // "foo is not a function"
答案 0 :(得分:5)
我可以从函数中删除此属性,只留下普通对象吗?
没有。函数(评估行为,而不是它们的对象属性)几乎是不可变的。
callability个对象取决于它们是否有[[call]]
个插槽。 spec says about those:
内部插槽是作为创建对象的过程的一部分分配的,可能无法动态添加到对象中。
(暗示他们也不能动态删除)。此外,“这些内部方法不是ECMAScript语言的一部分”和“不是对象属性”,这意味着它们不能被访问,设置,删除或操纵通过语言可以想象的方式。
[[call]]
个槽是各种对象的一部分,它们总是包含一个内部方法,但除了初始化(一次)之外,它们永远不会发生变异。他们有各种各样的:
[[call]]
用户定义的函数对象,在FunctionAllocate
[[call]]
内置函数对象,由环境隐式初始化[[call]]
绑定的函数对象,在BoundFunctionCreate
[[call]]
,如果代理目标也可以调用,则在ProxyCreate
的步骤7a中有条件地初始化正如您所看到的,无法更改甚至删除对象的[[call]]
插槽,甚至无法替换代理。你最好的选择是
throw
通过
从函数创建一个新的,不可调用的对象var obj = Object.assign(Object.create(Object.getPrototypeOf(fn)), fn);
答案 1 :(得分:0)
据我所知你不能。
这些函数有一个名为call()
的属性,它调用函数体(抱歉冗余)。
您可以将此属性设置为任何表达式,例如
foo.call = console.log('foo not a function');
但这不会阻止调用函数的主体。
由于您无法将其设置为函数,因此无法使用event.preventDefault()
函数。
答案 2 :(得分:-1)
这不是一个优雅的解决方案,其目的是创建"启用"属性作为标志,以了解该功能是否已启用:
var foo = function () {
if(!arguments.callee.enabled){
throw "function disabled";
}
console.log("Hello");
}
foo.enabled = true;
foo();
foo.enabled = false;
foo();