0

In vanilla javascript I can do:

run();
function run() {};

In angular though it seems I have to predefine all the functions on a scope before I can run them:

app.controller('MainCtrl', function($scope) {
  $scope.fxn = function() {
    $scope.status = 'working';
  };
  $scope.fxn();
});

Because this throws the error TypeError: Object #<Object> has no method 'fxn':

app.controller('MainCtrl', function($scope) {
  $scope.fxn();
  $scope.fxn = function() {
    $scope.status = 'working';
  };
});

Am I missing something? Is angular enforcing a best-practice?

1
  • 2
    It has nothing to do with Angular. Just javascript. You are trying to call a object method before you define it. Of course it will fail. Object methods don't hoist. Commented Feb 10, 2014 at 18:54

2 Answers 2

4

$scope is an object in angular.

In vanilla js, you cannot do:

var x = {};
x.alert("hi");
x.alert = function(msg) { alert(msg); }

When you do

run();
function run() {};

You have function hoisting going on, which is where all function definitions get "hoisted" to the top, so it works as if you had

function run() {};
run();

If you had done, on the other hand:

run(); //TypeError: undefined is not a function
otherrun(); //ReferenceError: otherrun is not defined
var run = function() {}

The difference, is again hoisting, this time it is variable hoisting. That code is the equivalent of:

var run;
run(); //TypeError: undefined is not a function
otherrun(); //ReferenceError: otherrun is not defined
run = function() {}

Where the declaration (but not assignment) of a variable is hoisted to the top.

It's all pretty confusing at first, but if you google javascript hoisting and read a few articles, you should get a good feel for how it works.

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

1 Comment

Thanks @dave, I am aware of hoisting but not of the nuances you showed. I assumed that function run(){} was the same as var run = function(){} and that declaring a global function was the same as assigning it to the window which is done implicitly.
1

The distinction is between function statements and function expressions. Function statements act as if they are lifted to the top of the current scope. Function expressions aren't. So

run();
function run() {}

is equivalent to

function run() {};
run();

However,

run();
var run = function () {};

is not equivalent to

var run = function () {};
run();

Rather, it's equivalent to

var run;
run();
run = function () {};

which will fail to run.

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.