-3

As far as I can tell, JS is function scoped and not block scoped, meaning objects declared inside (parenthesis) do not create a different execution context. However:

$('#firstBtn').click(function first() {
    console.log("first activated");
});

$('#secondBtn').click(function() {
    console.log("second activated");
    first();
});

Returns Reference Error function is undefined. The function first is being declared inside a parenthesis, so technically it should be available to other functions that call it from the scope it was declared at.

But this works:

var callDat = $('#firstBtn').click(function first() {
    console.log("first activated");
});

$('#secondBtn').click(function() {
    console.log("second activated");
    callDat.first();
});

My assumption is that since objects are functions, declaring a function inside an object can count as declared inside a different function scope even without curly braces. I however wish for a definitive answer on this.

Bar Akiva
  • 681
  • 1
  • 8
  • 19
  • 1
    In `function first() {` `first` is the alias created to call the function from itself. `first` is not accessible from outside of `first`. – Tushar Aug 05 '16 at 15:39
  • 1
    Have a look at [Named function expressions demystified](https://kangax.github.io/nfe/). Named function expression !== function declaration. For the second example you jump to the completely wrong conclusion. – Felix Kling Aug 05 '16 at 15:41
  • My bad, the second example does not work. However I had this question in mind before I came up with my "solution" so I think it should not be deleted, though maybe edited so as to not distract further readers from my original inquiry? – Bar Akiva Aug 05 '16 at 15:47
  • So, what is the actual question? – Jamiec Aug 05 '16 at 15:49
  • @Jamiec why is the function not available even though its not within curly braces. – Bar Akiva Aug 05 '16 at 15:51
  • 1
    All of them are *function expressions*. To create a function and put it in the current scope, you use *function declarations*. You can only determine if something is a function declaration or a named function expression by looking at the surrounding code: function declarations are statements, but function expressions are expressions. – gcampbell Aug 05 '16 at 15:53

4 Answers4

5

In your second example, the first you're getting is not the one you've declared above - its the jQuery.first method available to all jQuery objects.

This is checkable - clicking "First" and then "Second" below does not output "first activated" from a click to the second button.

var callDat = $('#firstBtn').click(function first() {
    console.log("first activated");
});

$('#secondBtn').click(function() {
    console.log("second activated");
    callDat.first();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="firstBtn">First</button>

<button id="secondBtn">Second</button>
Jamiec
  • 118,012
  • 12
  • 125
  • 175
4

Returns Reference Error function is undefined. The function first is being declared inside a parenthesis, so technically it should be available to other functions that call it from the scope it was declared at.

No. Function declarations create a variable in the scope they are declared with which has the same name as the function. Function expressions do not, even if they are named function expressions. (Named function expressions to create a variable of that name inside their own scope).

Further reading: JavaScript function declaration syntax: var fn = function() {} vs function fn() {}

My assumption is that since objects are functions,

Functions are objects. The reverse is not necessarily true.

declaring a function inside an object can count as declared inside a different function scope even without curly braces

No, it can't.

Community
  • 1
  • 1
Quentin
  • 800,325
  • 104
  • 1,079
  • 1,205
  • I have read that article and I somewhat understand this. You answer my second example - but what about the first? Both are declared functions. – Bar Akiva Aug 05 '16 at 15:53
  • 3
    @BarAkiva — Neither are function declarations. You have only function expressions. – Quentin Aug 05 '16 at 15:57
1

In first example you actually do create a scope - this:

$('#firstBtn').click(function first() {
    console.log("first activated");
});

is actually this:

(function first() {
    console.log("first activated");
})

And as such is not available to other scopes

Now - if you'll declare it as such:

function first() {
    console.log("first activated");
}

$('#firstBtn').click(first);

$('#secondBtn').click(function() {
    console.log("second activated");
    first();
});

you won't get the error

eithed
  • 3,110
  • 3
  • 34
  • 46
0

It's a "function literal" or "function expression" which only returns a function as a value, but does not define it in the surrounding function scope as a variable. It does, however, have its own scope. See my snippet below for something very interesting:

var counter = 0;

// function "b" is acting as a value to be given to "a"
var a = function b() {

  alert(counter);

  counter++;

  // both "b" and "a" are accessible in here
  if(counter < 3) b();

};

a(); // only a is accessible here

Because it's not obvious from the syntax, the form...

function func() { ... }

...may be replaced by the following to be more clear:

var func = function() { ... };
BCDeWitt
  • 4,087
  • 1
  • 16
  • 31