2

In browsers, setTimeout lives in window or self, which are equal. In web workers, only self is present. On Node.js, global represents the global context and setTimeout exists within it. And there are more than just these two javascript platforms.

I need to call a setTimeout function but I have an arbitrary number of arguments to pass to it - 3rd and following arguments are passed to the callback. In browser of web worker, this works:

setTimeout.apply(self, [alert, 666, "Hello"])

Node.js console accepts this:

setTimeout.apply(global, [console.log, 500, "Hello."])

So what's the general answer? How to use apply on function with unknown or variable this scope without breaking that scope?

Edit to clarify: because it appears one solution might be to get access to global object using some procedure that detects it, I want to clarify that I was hoping to fetch this scope from the function I'm gonna call. Something like inversion of .bind - get the this scope and apply it, so that it works even on non global functions. The idea:

setTimeout.apply(setTimeout.getThisObject(), [alert, 666, "Hello"])
Tomáš Zato
  • 50,171
  • 52
  • 268
  • 778
  • What about `this`? Means `global` in node and `window` in browsers... – Rudie Oct 24 '15 at 23:52
  • 2
    Are you asking how to get a reference to the global object in a cross-platform way? See [Getting a reference to the global object in an unknown environment in strict mode](http://stackoverflow.com/q/9642491/1529630) – Oriol Oct 24 '15 at 23:53
  • `this` does not mean global when the function that executes the code belongs to an object. Which is quite often in bigger applicatons that mimic OOP. – Tomáš Zato Oct 25 '15 at 00:22
  • @TomášZato If possible, can clarify what actual Question is ? What is expected result ? – guest271314 Oct 25 '15 at 00:34
  • I am sorry if I wasn't clear for the first time and I also admit @Oriol proposed possible solution already, but when asking the question, I hoped for **getting the `this` scope** bound to a function. The opposite of bind, which *sets* the `this` scope. – Tomáš Zato Oct 25 '15 at 00:37
  • @TomášZato At edited Question : _"want to clarify that I was hoping to fetch this scope from the function I'm gonna call."_ , "fetch `this` _from_" or _set_ `this` scope _at_ ? Why not _set_ `this` scope ? Can create stacksnippets , jsfiddle to demonstrate actual application of described procedure ? , Detail expected results that would be different from using `.bind()` ? – guest271314 Oct 25 '15 at 00:37
  • If the sample pseudo code isn't clear enough to picture whether I'm setting or getting the scope, I don't know what can be clearer. Especially then, since I named the method **`getThisObject`**, not `setThisObject`. – Tomáš Zato Oct 25 '15 at 00:39
  • 1
    @TomášZato Your edit seems to assume the value of `this` becomes fixed when you create a function. That is false in general, `this` may depend on how you call the function. – Oriol Oct 25 '15 at 00:39
  • Not even that since `bind` exists. – Tomáš Zato Oct 25 '15 at 00:41
  • @TomášZato Then, are you asking, given a reference to a function which you know was created with `bind`, how to get that bound `this`? I don't think you can. – Oriol Oct 25 '15 at 00:46
  • @Oriol Actually, I was about to start a new question about that once I have this one answered. But it seems javascript specification regarding this in functions till needs some work. – Tomáš Zato Oct 25 '15 at 00:47

1 Answers1

0

this corresponds to the global object when called outside of any function scope. Thus, simply bind this to a variable outside any function scope:

var globalObject = this;
// ...rest of your code...
function foo () {
  setTimeout.apply(globalObject, ...)
}

Or, in IIFE style:

(function (global) {
  // ...rest of your code...
  setTimeout.apply(global, ...)
}(this))

You might even want to have the IIFE's this bound to the global this, although that may prove a bit confusing:

(function (global) {
  // ...rest of your code...
  setTimeout.apply(this, ...)
  var foo = function () {
    setTimeout.apply(global, ...)
  };
}.bind(this)(this));
Félix Saparelli
  • 8,424
  • 6
  • 52
  • 67