是否可以将可调用对象设为不可调用?

问题描述 投票:0回答:4

在 JavaScript 中,函数是可调用的。

我可以从函数中删除这个属性,只留下一个普通对象吗?

var foo = function () {};
foo.[[callable]] = false; // pseudocode
foo(); // "foo is not a function"
javascript
4个回答
11
投票

我可以从函数中删除这个属性,只留下一个普通对象吗?

不。函数(评估行为,而不是它们的对象属性)几乎是不可变的。

对象的可调用性取决于它们是否有

[[call]]
槽。 规范说明了这些

内部槽是作为创建对象过程的一部分进行分配的,并且可能不会动态添加到对象中。

(这意味着它们也不能动态删除)。此外,“这些内部方法不是 ECMAScript 语言的一部分”和“不是对象属性”,这意味着它们不能通过语言以任何可以想象的方式访问、设置、删除或操作。

[[call]]
槽是各种对象的一部分,它们始终包含内部方法,但除了初始化(一次)之外,它们永远不会发生变化。它们有多种类型:

如您所见,无法更改甚至删除对象的

[[call]]
插槽,即使在代理上也是如此。你最好的选择是

  • 在不合适的状态下调用该函数时
    throw
  • 通过

    从函数创建一个新的、不可调用的对象
    var obj = Object.assign(Object.create(Object.getPrototypeOf(fn)), fn);
    

0
投票

据我所知你不能。

这些函数有一个名为

call()
的属性,它调用函数的主体(抱歉有些冗余)。

您可以将此属性设置为任何表达式,例如

foo.call = console.log('foo not a function');

但这不会阻止函数体被调用。

并且由于您无法将其设置为函数,因此您无法使用

event.preventDefault()
函数。


0
投票

我喜欢对Bergi已经提到过的内容提供额外的观点,也受到OP问题中这个答案的鼓励。

目的是什么? – user3749178 4 月 16 日 16:18

.

@user3749178 好奇心。 – 本·阿斯顿 4 月 16 日 16:19

除了依赖于
var obj = Object.assign(Object.create(Object.getPrototypeOf(fn)), fn);

ES6
之外,还有一种
ES3
兼容方法可以将函数对象包装到
callable
对象中。因此,这些对象不再可以由调用运算符 () 调用,但此类对象仍然公开两个调用方法
call
apply
。 由于这种方法一方面可以防止函数对象被
()
(方法/函数)或
new
运算符(实例化)调用,但另一方面它仍然支持委托(基于函数的混合/特征)。

Function.toApplicator

的要点托管代码
    


-2
投票

var foo = function () { if(!arguments.callee.enabled){ throw "function disabled"; } console.log("Hello"); } foo.enabled = true; foo(); foo.enabled = false; foo();

	
© www.soinside.com 2019 - 2024. All rights reserved.