Why javascript functions behave differently?

Hi,

Its a very basic question and might have a simple answer , i searched here and on web but could not find an answer to it …

Here is my question - If i write

var a;
console.log(a);
a = 10;
console.log(a);

I get

undefined
10

But if i write -

test();
var test = function () {
    console.log("Unknown Called");
}
test();

I get

test is not a function,

why if i am doing a function call assigning it to a var am i not getting the output on second call of test() once i set the value…

Kindly help me with this … Thanks

It’s because you called test before assigning a function to the test variable. You won’t get an error if instead var test = function() {...} is at the top.

@kevcomedia - Thank , i get the point , but if i am calling a function like an expression by assigning it to var test , why does once after i assign it , it gives the output, like any variable would do, wny it just shows the error and then does not give output to second function call ?

You see its like

test called - but its undefined

test defined

test called again – still no out put , like in case of var it gives 10 after assignment …

Trying to make a function call to something that isn’t a function (like the unassigned test variable) throws an error (a TypeError to be exact). Usually when an error is thrown, your program crashes and won’t continue.

Using unassigned variables for most other purposes (like plain console.logging them) is allowed by the JS engine though, and it won’t crash your program (though you might encounter some subtle bugs along the way).

Your JS program already crashed at line #1. It wouldn’t even see the next statements, no matter how correct they are.

@owel @kevcomedia -Thanks, But that is the question why it crashes at line 1 , if i am trying to create a function expression using var test , just like in case of any other var , like var a , the JS engine if it finds any (var) ,it assigns undefined … Then why not in case of function expression…

Kindly guide me here , is my thinking wrong or its just the way the person made the language …

I think I see what you’re trying to ask.

If this were a compiled language, you won’t be even be able to run your program. Right at compilation, it will tell you that test() is undefined.

In this case, the JS engine has declared “a” to be a variable (in this case, an allotted space in computer memory) but has not assigned a value to it… thus, when you asked JS what’s the value of “a”-- it answered back “undefined”

it’s a different matter asking the computer to execute a non-existent piece of code… i.e. trying to call test() without having declared test and it’s content beforehand.

@owel - Thanks, so if i am right the JS engine can tolerate a variable undefined and if we call it and the call corresponds to a call to a primitive type, but not if the var points specifically to a function(Object type) and the function definition is yet to be declared in that case its an error and not some undefined to be returned in case of some primitive data types only …

As if i try -

console.log(a);

a = {};

console.log(a);

This also throws error , so does javascript only allow var to be undefined(called before defined) and not throw an error in case of primitive data types and not objects ? Kindly guide …

I think one of the ideas that you’re missing here is “hoisting”. JS will “hoist” variable declarations (but not their initializations) up to the top of code. So, something like …

console.log(a);
// undefined

var a = 5;

console.log(a);
// 5

…works because what JS is really seeing is:

var a;

console.log(a);
// undefined

a = 5;

console.log(a);
// 5

But something like …

console.log(a);
// Uncaught ReferenceError: a is not defined

a = 5;

console.log(a);
// never reaches this code

… will generate an error because there is no declaration to hoist…

This will work because there is an implicit declaration of the variable:

a = 4
// JS infers "var a = 4"

console.log(a);
// 4

… but this won’t because implicit declarations don’t get hoisted:

console.log(a);
// Uncaught ReferenceError: a is not defined

a = 4
// JS infers "var a = 4"
// but doesn't hoist

Again, with:

console.log(a);

a = {};

console.log(a);

There is no declaration to hoist. But if you add a var in there,

console.log(a);
// undefined

var a = {};

console.log(a);
// {}

… because what JS is really seeing is …

var a;

console.log(a);
// undefined

a = {};

console.log(a);
// {}

So, what happens in the one that bothered you?

test();

var test = function () {
    console.log("Unknown Called");
}

test();

The variable test gets hoisted, so JS really sees this:

var test;

test();
// this isn't a function yet, JS doesn't know how to call it
// it's a variable because of hoisting, but it has no value
// and can't be called as a function

test = function () {
    console.log("Unknown Called");
}

test();
// JS could call because it's a function now

But at that point, test is not a function, it is a undefined variable. You can’t call an undefined variable as a function, JS doesn’t know what to do with it. You can console.log and do other stuff to an undefined but you can’t try to call it as a function.

3 Likes

@ksjazzguitar - Thank you so much for this wonderful explanation, i now understand that i cannot call a function as undefined , however i feel like not just in JS but in all languages , they will say a = 1 , a= 1 , a= 1 and then a= 2 and give some explanation for the break in logic , like here -

They say that in javascript functions are objects , ok , so i take function as objects – but when i run

console.log(a);

var a = {};

console.log(a);

Out put

undefined 
{}

But for

test();
var test = function () {
    console.log("Unknown Called");
}
test();

Oh no i not right, because function cannot return undefined , but they just said

in JS functions are objects …

Well here they use hoisting concept , but then why say functions are objects if they do not behave same in real world in all cases …

My point being why not return function as undefined as well if you can return an object as one and on top of that say functions are objects in JS …

I guees i will just have to get used to this …

If you want a function that can get hoisted, initialize it with function functionName(){};

For example:

test();
function test() {
console.log(“True”);
}
test();

“True”
“True”

You are not correctly comparing the two. You are comparing logging the value of the variable with trying to execute it. Executing a gives the same result as executing test. Also, logging a gives the same result as logging test:

a();  // TypeError
test(); // TypeError

console.log(a); // undefined
console.log(test); // undefined

var a = {};
var test = function(){};

@BenGitter - Thank you so much you just solved my confusion for which i was ranting :slight_smile: and a big thanks to @ksjazzguitar for explaining hoisting :slight_smile:

in JS functions are objects …

Yes, but not all objects are functions. And I think you miss the point that in your example:

console.log(a);

var a = {};

console.log(a);

… the variable a is not getting hoisted as an object or function or whatever. It is simply a variable being declared. As a string, a number, a boolean, an object (be it function or array)? Nope, it’s undefined.

Oh no i not right, because function cannot return undefined , but they just said

I think functions can return undefined, you just can’t call an undefined variable as a function.

1 Like