3
function def() {
    console.log(this.x)
}

var f = def.bind({ x:777 })
f() // prints 777

The bind creates a function f which is identical to def, except that within f, this is set to { x:777 }.

Is it possible to access the object f was bound to outside of f? E.g., console.log(f.this.x) (but that doesn't work). Or is it impossible for code that comes after to see what object f was bound to?

Tim Goodman
  • 23,308
  • 7
  • 64
  • 83
exebook
  • 32,014
  • 33
  • 141
  • 226
  • how can u call a f().. its not yet declared as funciton.. – sasi Mar 08 '13 at 06:25
  • `bind` changes the context of `this` inside a function but it doesn't execute it like `call` and `apply`. I don't see what's the point of your code. `x` won't be accessible I don't think so. – elclanrs Mar 08 '13 at 06:26
  • 1
    So you're basically asking how to get the bound value of `x` from the `this` argument? – Blender Mar 08 '13 at 06:26
  • bind() is an amazing part of javascript. see here: http://msdn.microsoft.com/en-us/library/ie/ff841995(v=vs.94).aspx I am trying to understand it better. it binds one data and one function into a _new_ function+data object. I am curious if this data can be accessed externally now, or this is a perfect way to create private objects. – exebook Mar 08 '13 at 06:30
  • I think I get it. `var f = def.bind({ x:777 })` creates a function `f` which is the same as `def` except that in `f`, `this == { x : 777 }`. So that object `{x : 777}` is stored somewhere, as seen by the fact that the value is used when x is called. exebook wants to read the `{ x : 777 }` back out of the function, e.g. `console.log(f.this.x)` (but that doesn't work) – Tim Goodman Mar 08 '13 at 06:31
  • yes, the object `{x:777}` is now somewhere in heap, and it could be that GC will free it when `f()` is not used any more. not that I _want_ to read the x outside of `f()`, I rather _want to know_ if that's possible or not. – exebook Mar 08 '13 at 06:36
  • 1
    I've expanded your question a bit, as I think you were getting some downvotes because people didn't understand what you were asking. I hope you don't mind. – Tim Goodman Mar 08 '13 at 06:41
  • 1
    I have to disagree with the close vote. This is a perfectly legitimate question, which I would also like to know the answer to. He wants to know, **given a function bound to an object using `bind`, is it possible to extract the bound object from the function** – Tim Goodman Mar 08 '13 at 06:47

2 Answers2

8

I found some useful information on bind here: http://dmitrysoshnikov.com/notes/note-1-ecmascript-bound-functions/

bind as specified in ECMAScript 5 produces a sort of lightweight function (which differs in some ways from usual functions, as described in the link above. Basically it provides a wrapper for calling the target function, and maintains internal properties which include the target function, the bound this, and the bound arguments. As these are internal properties, they aren't accessible in the way the OP is asking about (you can't take an arbitrary bound function f and do something like f.getBoundThis()).

It's worth noting that bind is not unique in capturing some state. Closures also capture state. However, bind (as specified in ECMAScript 5) is not a closure, because closures capture variables whereas bind captures values.

Here's an example:

(function () {
    var x = 2;

    function thisSquared() { return this * this; }
    f = thisSquared.bind(x);

    g = function() { return x * x; } // g is a closure

    console.log(f()); // Squares the captured value (2), prints 4
    console.log(g()); // Squares x, prints 4

    x = 3;
})();

console.log(f()); // Squares the captured value (still 2), prints 4
console.log(g()); // Squares x, prints 9

Some previous implementations of bind (written in JavaScript before ECMAScript 5) didn't have this distinction from closures.

Tim Goodman
  • 23,308
  • 7
  • 64
  • 83
0

No, you cannot access it because the object is only bound temporarily to the function for the lifetime of the call, it does not change the functions prototype.

Rob M.
  • 35,491
  • 6
  • 51
  • 50
  • But what if the binding happens within some function, and then the bound function is returned? Then you only have the function, but the bound object still exists. The question is if you can get the bound object from the function it's bound to. – Tim Goodman Mar 08 '13 at 06:43
  • 1
    Surely this will print `777`, but the question is can you access the bound object if you **only** have a reference to a function instance returned by `bind()`. – exebook Mar 08 '13 at 06:47
  • The short answer to both of your comments is "yes". Of course it depends on the implementation, but if you can either: 1) ensure all bound functions return `this` or 2) assign `this` to a variable bound to an outer function (not really ideal). `bind`, `call`, and `apply` all return the value the function they are executing returns. – Rob M. Mar 08 '13 at 06:51
  • Rob M. I am not sure I understand your answer. Do you mean that it is possible to access the bound object somehow by using `apply()` or `call()`? – exebook Mar 08 '13 at 06:53
  • @RobM., I'm not sure you're understanding. If I have a function `f` which was created using `bind` as in exebook's example, how do I extract the object that was passed to the `bind`? Obviously if I stored the object in some variable, or if `f` returns the object, then I can see it. But *in the general case*, is there some way to read the object given `f`. E.g., I could imagine an `f.this`, but it doesn't exist. – Tim Goodman Mar 08 '13 at 06:56
  • You are right, i misunderstood the question and edited my answer; sorry for the confusion. – Rob M. Mar 08 '13 at 06:57
  • Ok, you can return the `this` object from he function and then access it's members, but originally the function was not returning anything, and I ephasized this in the question that I want to access from outside, without modifying the function. But question was immediately edited by Blender who removed the line numbers and made the question incomplete. – exebook Mar 08 '13 at 07:02
  • Hmm, that's still relying on the fact that the function returns this. The question is more about the general case I think. Consider: `function sq() { return this * this; } f = sq.bind(10); f()` Is there a way to determine, given `f`, whether it was bound to 10 or -10? – Tim Goodman Mar 08 '13 at 07:03
  • Yeah, the question is given an *arbitrary* `f`, which is produced using `bind`, is there a way to determine what object it was bound to? Answers that require `f` to return the object, or require you to store the object in a variable before binding, are missing the point. The object is already stored *somewhere*. The question is, is it possible to access it. – Tim Goodman Mar 08 '13 at 07:07
  • @RobM., I think you are right. At least, I can't figure out a way to do it. :) – Tim Goodman Mar 08 '13 at 07:12
  • Regarding your latest edit, it seems the object is bound not just temporarily but for the entire lifetime of `f`. That is you can keep calling `f` again and again, and each time it accesses some stored object. It's not a matter of the object going away, it's just (apparently) inaccessible. – Tim Goodman Mar 08 '13 at 07:30