1

I have declared a function in file so that it becomes global:

function speakService() {

    var speakService = {};

    var speak = function(word) {
        console.log(word);
    };

    speakService.speak = speak;

    return speakService;
}

Using AngularJS, I want to add this service as dependency:

angular
    .module('login', ['ngRoute'])
    .factory('speakService', [function() {
        var speakService = speakService();
        return speakService;
    }]);

But as soon as the interpreter hits the line:

var speakService = speakService();

the speakService()-function is undefined. If I change the speakService variable to speakSvc like this it works fine:

var speakSvc = speakService();

Can somebody explain why my global function is undefined when declaring a local variable with the same name?

Regards!

1
  • You don't need to create a named variable inside your speakService function. Just return an object literal with an assigned speak function. Commented Nov 11, 2016 at 18:52

3 Answers 3

4

The reason why the variable appears to be undefined is hoisting. When you write something like var x = 3 the definition of x is hoisted to the top of the current scope (functional in this case since you are using var). The assignment itself happens when you hit that particular line.

So in your specific case, when you enter the scope of that variable you define it var speakService first, which hides the function speakService from the rest of the scope. Then you try to execute the line speakService = speakService() and since speakService is just an uninitialized variable you get undefined.

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

1 Comment

Indeed, the declaration of a variable with the same name hides the global variable. The global variable is still available, e.g. by refencing it using the windows object. I just tested this out. I am not sure what hoisting has to do with this. Even without moving the variable declaration to the top of the function the global variable would be hidden - or am I wrong?
2

It's because of javascript's hoisting

function() {
        var spkService = speakService();
        return spkService;
    }

Will be same as

function() {
        var spkService; //Declaration moved to top
        spkService= speakService(); //here spkService is undefined
        return spkService;
    }

Comments

1

Like others have said, your issue is hoisting. Just return an object literal and use the IIFE pattern.

var myService = (function speakService() {
    var speak = function(word) {
        console.log(word);
    };
  
    return {
      speak: speak
    };
})();

myService.speak("TEST");

Comments

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.