Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to make a callable object non-callable?

Tags:

javascript

In JavaScript, functions are callable.

Can I remove this attribute from a function, leaving only a normal object?

var foo = function () {};
foo.[[callable]] = false; // pseudocode
foo(); // "foo is not a function"
like image 406
Ben Aston Avatar asked Sep 13 '25 10:09

Ben Aston


1 Answers

No. Functions (the evaluation behaviour, not their object properties) are pretty much immutable.

The callability of objects is determined by whether they have a [[Call]] slot. The spec says about those:

Internal slots are allocated as part of the process of creating an object and may not be dynamically added to an object.

(and it is implied that they cannot dynamically be removed either). Furthermore, “internal methods are not part of the ECMAScript language” and “are not object properties”, which means they cannot be directly accessed, set, deleted or manipulated in any imaginable way by the means of the language.

[[Call]] slots are part of various objects, where they always contain an internal method, but they are never mutated except for their initialisation (once). They come in various kinds:

  • [[Call]] of user-defined function objects, initialised in step 8 of FunctionAllocate
  • [[Call]] of builtin function objects, initialised implicitly by the environment
  • [[Call]] of bound function objects, initialised in step 6 of BoundFunctionCreate
  • [[Call]] of some proxy objects, initialised conditionally in step 7a of ProxyCreate iff the proxy target is callable as well

As you can see, there is no way to alter or even remove the [[Call]] slot of an object, not even on proxies. Your best bet is

  • make the function throw when called in an inopportune state

  • create a new, uncallable object from the function by means of

    var obj = Object.assign(Object.create(Object.getPrototypeOf(fn)), fn);
    
like image 68
Bergi Avatar answered Sep 15 '25 00:09

Bergi