2

I'm trying to use variables placed inside a function. I'm not looking to do anything particular with this piece of code, but I want to figure out why bind / apply / call work for objects, and not functions.

function another () {
    this.var = 'another test'
}

function test (){
    this.var = 'test123'
    console.log('this.first: ',this.var);
}

var bind = test.bind(another);
console.log('bind: ', bind());
10
  • If you check another.var after running this, you should see it set to 'test123'. What were you expecting? Commented Jul 27, 2014 at 21:39
  • To print the variable from another() = 'another test' Commented Jul 27, 2014 at 21:41
  • Why, when you overwrite it with 'test123' before you log anything? Commented Jul 27, 2014 at 21:42
  • 3
    The code in the function another is never executed, so the string 'another test' is not assigned to anything. You can't output a value that doesn't exist. You are writing out what the test function returns, but it doesn't return any value. Commented Jul 27, 2014 at 21:44
  • 1
    @seasick: No. The bind method returns a new function that executes the original one, bound to a context. Commented Jul 27, 2014 at 22:09

2 Answers 2

3

.bind() works just fine for functions. It just doesn't do what you think it does.

See, functions are objects too. And treating them like objects doesn't mean they get called.

function a() { console.log("a was called"); }
function b() { console.log(this); }

var bound = b.bind(a);
bound();  // logs "function a() { }" in my console

In your case, once you've bound test to another, you have a new function that works just like test, but where this means another, and thus this.var means another.var. And all of this happens without another ever getting called.

I'm not sure entirely how you expect your code to work, cause it doesn't make much sense as it stands. But if you were to examine things after you run it, you would find that another.var now has the value 'test123'.

Even if you said another() beforehand, it wouldn't matter. Firstly because another isn't bound to anything, so to it, this means the global object. In a browser, another() would basically just be setting window.var. But secondly, test sets its own value -- so even if both functions had the same idea of what this.var means, test would overwrite it with 'test123'.

Sign up to request clarification or add additional context in comments.

Comments

1

This will log "another test", since this defaults to window:

function another() {
    this.foo = 'another test';
}

another();

console.log(window.foo);

edit:

// define function object window.first:
function first() {
    this.foo = 'first';
}

// define function object window.second:
function second() {
    this.foo = 'second';
}

// call window.first, sets window.foo to 'first':
first();

// set window.bound to a new function object which
// runs second in the context of the object first:
var bound = second.bind(first);

// call window.bound, which sets window.first.foo to 'second':
bound();

// call second, which sets window.foo to 'second' then logs the return
// value of second, which is undefined:
console.log('second: ', second());

6 Comments

Please also explain why you shouldn't do this.
It isn't self-evident? :-)
Yeah, s/explain why/state that/ after your edit :-)
@seasick: Do tell. What did you expect it to do
I called another(), then bound it to another, then called the newly bound function
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.