1

Given the following:

function x() {

    this.abc = 1;

    function f1() {
       alert(this.abc);
    }.bind(this)

    var f2 = function b() {
       alert(this.abc);
    }.bind(this);
}

What I would like is for the "this" of the outer function to be available inside the f1 and f2 functions.

Why is it that VS2013 tells me there's a syntax error with the bind(this) on function f1() ?

Samantha J T Star
  • 26,790
  • 72
  • 224
  • 390
  • Missing semicolons, at a guess. – Mitya May 12 '14 at 14:12
  • `SyntaxError: Unexpected token .` on the first bind. Replace the 2nd line with `var a = function(){`. Also, you're overriding `a` with your `var a = function b() {`. What are you trying to do? – Cerbrus May 12 '14 at 14:13
  • possible duplicate of [var functionName = function() {} vs function functionName() {}](http://stackoverflow.com/questions/336859/var-functionname-function-vs-function-functionname) – Bergi May 12 '14 at 14:20
  • It's telling you there's a syntax error because there **is** a syntax error. Note that the syntax used to define "f1" is **different** than that used to define "f2". If you changed it to match (`var f1 = function() ...`) then it'd work. – Pointy May 12 '14 at 14:34
  • I thought it was possible to declare a function in two ways which is what I was trying to do. I do realize they are different and that was the point of the question. Sorry if I was not more clear. – Samantha J T Star May 12 '14 at 14:38
  • Sorry, it was clear; I was just trying emphasize that it's that very difference which is the core of the issue. I just had an idea for a different way to explain; I'll extend my answer. – Pointy May 12 '14 at 14:41

1 Answers1

5

There's a difference between a function declaration statement and a function instantiation expression. Both involve the keyword function, but a declaration statement cannot immediately be used as a reference to a function. A function instantiation expression is part of the expression grammar, so it can be used freely in that context as a reference to a function because that's what it evaluates to.

You can of course do this:

(function a() {

}).bind(this);

though without using the return value from .bind() it's not very useful.

If the first token in a statement is function, then you've got a function declaration statement. If the first token is not function, then you've either got another sort of keyword-introduced statement (for, return, var, try, whatever), or else you've got an expression statement. In that expression (or in any expression in another context), your function instantiations are part of the expression grammar and the value can be used as a reference to a function.


Here's another way to think about the problem. Let's pretend that there is only one way to instantiate a function in JavaScript, and that's the function expression. That is, let's pretend that any use of the function keyword means to instantiate a function and return a reference to that function as it's value.

Now, thinking generally about expressions and the things that participate in expressions, the point is to compute some sort of value. When you need the value 5 as part of an expression, you put 5 in its place and that's that. By itself, 5 is a valid expression, so this is not a syntax error:

5;

What does that do, however? It does nothing. Similarly, in our make-believe JavaScript without function declaration statements,

function foo(a, b) {
  return a + b;
};

would also do nothing at all. What would happen is simply that the function would be instantiated but thrown away because the value — the reference to the instantiated function — is not saved as the value of a variable or passed to some function or anything else. In this make-believe JavaScript, you'd use

var foo = function(a, b) {
  return a + b;
};

all the time.

The language design does have function declaration statements, however. As a simplifying approach, the language just recognizes a statement whose first token is the keyword function as a completely different sort of statement than an expression statement that happens to contain a function instantiation. There are other ways in which the problem could have been addressed (such as the use of a different keyword), but I suspect that there'd still be confusion.

Note that there are JavaScript programmers who strongly prefer using var declarations for functions. It's a matter of style really.

Pointy
  • 371,531
  • 55
  • 528
  • 584
  • What I was wanting to do was use the two ways to declare a function but I need to have the "this" from outside available to the inside of the functions. I will change the question very slightly to make it more clear. Thanks – Samantha J T Star May 12 '14 at 14:28
  • @SamanthaJ the second way (with the `var` declaration) will work just fine. – Pointy May 12 '14 at 14:29
  • thanks. It does work fine but I am a bit confused because I thought the first way would work also. – Samantha J T Star May 12 '14 at 14:35
  • @SamanthaJ right - the reason really is just a matter of how the language deals with the syntax ambiguity. When the statement starts with `function`, then it's a whole different affair than if it doesn't. – Pointy May 12 '14 at 14:38