0

I am trying to find out how to get this without invoking function or at least not invoking the original function. This requires expert understanding of javascript. It may not be even possible to begin with. But i think if it's it'd save lot of time writing by not using place holder functions like in events, callbacks, and setTimeouts...

This should refer to object the function belongs to with out directly invoking it.

The thing i wanted to do:

say i have function like this:

function add2(x) {
   return x+2;
}

and then do this:

setTimeout(add2**pass parameter without invoking it**, 1000);

If i had done this setTimeout(add2(3), 1000); it would have executed right away.

so to do it other way, i do this:

Function.prototype.pass= function(){ 
          var func=this, args=arguments;
          return function() {
          func.apply(this,args);
        }
};

then call it like this:

setTimeout(add2.pass(3), 1000); //5

this is great and all and works. But this fails when it's inside a object and need to access object's data. The this in it always refer to function itself. So doing this would give an error:

var o= {
            a:3,
            log:function(){console.log(this.a);}
};

o.log.pass(); //will just output the log function itself.

i could have solved it only if could pass correct this reference at line func.apply(this,args);.

Muhammad Umer
  • 17,263
  • 19
  • 97
  • 168
  • Are you looking for `setTimeout(function(){ add2(3) }, 1000);` ? – Denys Séguret Apr 15 '14 at 19:33
  • i am trying to avoid that if possible – Muhammad Umer Apr 15 '14 at 19:33
  • 1
    You're looking for `bind`. `setTimeout(add2.bind(null,3),1000)` , first argument is the `this` value, from then on the parameters. – Benjamin Gruenbaum Apr 15 '14 at 19:34
  • 1
    @MuhammadUmer - Why, that's the way to do it, what you're doing is insain ? – adeneo Apr 15 '14 at 19:34
  • isn't writing `add2.pass(3)` much more convenient then writing `function(){add2(2);}`...i mean there should be a way to pass reference of a function along parameters without breaking it. – Muhammad Umer Apr 15 '14 at 19:36
  • *"This should refer to object the function belongs to with out directly invoking it."* This only works if you are **explicitly** binding `this` to a specific value. – Felix Kling Apr 15 '14 at 19:36
  • There is such a way and that way is `.bind` , also, your code for bind is mostly correct see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind#Compatibility for a polyfill. – Benjamin Gruenbaum Apr 15 '14 at 19:37
  • 1
    @MuhammadUmer - There is a way to do that, but anonymous functions are like the lifeblood of javascript, and you're extending the Function prototype to avoid them ? – adeneo Apr 15 '14 at 19:37
  • If typing less is the goal, create a convience function -> http://jsfiddle.net/PHW7C/1/ – adeneo Apr 15 '14 at 19:40
  • My first another question about this...http://stackoverflow.com/questions/23073668/are-there-any-drawbacks-in-doing-this-adding-a-new-function-in-prototype-that-r – Muhammad Umer Apr 15 '14 at 19:44

1 Answers1

2

You can use .bind():

setTimeout(add2.bind(this, 3), 1000);
//                         ^ the parameter

The second argument is the argument to pass to the function when it is called.

MrCode
  • 63,975
  • 10
  • 90
  • 112
  • will it work with object also...like `obj.add2.bind(this,3);` – Muhammad Umer Apr 15 '14 at 19:36
  • @MuhammadUmer: Depends on the context. In that case you probably need `obj.add2.bind(obj,3);`. Check out the documentation. – Felix Kling Apr 15 '14 at 19:37
  • You probably want to bind add2 to obj there instead. – Benjamin Gruenbaum Apr 15 '14 at 19:37
  • @MuhammadUmer yes if your object has an `add2` method. Be careful with the first argument `this`, which sets the context, and that can be important if your object method references `this`. – MrCode Apr 15 '14 at 19:39
  • exactly...so i am trying to know if there is a way to get reference to object instead of passing it explicitly. So i can automate it. So instead of passing obj as this every time i only have to pass parameter. – Muhammad Umer Apr 15 '14 at 19:40
  • 1
    @MuhammadUmer: Nope, not possible. Functions are first-class objects, and there is no implicit relationship to their "containing" object. Imagine `function foo() {}; var a = {m: foo}; var b = {m: foo};`. Which object should `foo` refer to in that case? – Felix Kling Apr 15 '14 at 19:40
  • I know it won't work, but couldn't there be a way to tell this by the way it's written..for example: `a.m....` should yield that foo should refer to object `a` now. – Muhammad Umer Apr 15 '14 at 19:46
  • and thus `b.m..` should make foo refer to b. – Muhammad Umer Apr 15 '14 at 19:47
  • 1
    @MuhammadUmer: Theoretically yes, the specification defines a "Reference" type, which holds information about the object and the property name. However, the evaluation rules dictate that `x.y` has to resolve to the value of `x.y`. So, it's just how JavaScript works. – Felix Kling Apr 15 '14 at 20:28