Let’s say I have an object obj
with a function f1
that accept two parameters a
and b
. The function is called as follows:
obj.f1(a,b);
Now I want to make f1
accessible without calling obj
as follows:
f1(a,b);
Is this possible? If so, how may I achieve this?
Edit: If yes, is there a way to make all functions in the object global without knowing the specific functions?
Advertisement
Answer
While its not the best idea to do this, you can add properties to the global window
object (if running this in the browser, if you’re using node, then you can refer to global
– here I’m using globalThis
so this works in both environments), and then call these without needing to prefix obj
. Adding properties to window
(ie: globalThis) isn’t a good idea usually because you can end up overwriting pre-existing properties on the window. With that being said, here is how you may go about it:
const obj = {x: 1, y: function() { console.log("hello"); }} Object.entries(obj).forEach(([key, val]) => { if(typeof val === "function") globalThis[key] = val; }); y();
Keep in mind, if your object’s methods refer to this
, then when calling your method the this
will get bound to the global object (ie: window
), or, if you’re running this in strict mode, then it will be undefined
.
Here are some examples of some of the caveats mentioned above:
Modifying pre-existing properties: The window object has some pre-existing properties. One such property is the name
property, which JS enforces to be a string. This means that if you have a method called name
in your object, it will be converted to a string once it gets added to the window
:
const obj = {x: 1, name: function() { console.log("hello"); }} Object.entries(obj).forEach(([key, val]) => { if(typeof val === "function") globalThis[key] = val; }); console.log(typeof name); // string name(); // Crash: "Uncaught TypeError: name is not a function"
Losing the this
inside your method: If your method refers to this
, then you can expect your method to no longer work, as it loses its this
binding:
const obj = {x: 1, y: function() { console.log(this.x); // undefined (as `this` now refers to window) }, z: function() { 'use strict'; console.log(this.x); // Crashes, because this is undefined when in strict-mode }} Object.entries(obj).forEach(([key, val]) => { if(typeof val === "function") globalThis[key] = val; }); y(); // undefined z(); // "Uncaught TypeError: Cannot read property 'x' of undefined"
To help rectify the above issues with this
, you can consider binding your method as you assign it to the window so its context is predefined:
const obj = {x: 1, y: function() { console.log(this.x); // this is bound to `obj` (via the .bind() method) }, z: function() { 'use strict'; console.log(this.x); // this is bound to `obj` (via the .bind() method) }} Object.entries(obj).forEach(([key, val]) => { if(typeof val === "function") globalThis[key] = val.bind(obj); }); y(); // 1 z(); // 1