km6zla
km6zla

Reputation: 4907

Why doesn't AngularJS controller scope work like regular javascript scope?

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?

Upvotes: 0

Views: 127

Answers (2)

dave
dave

Reputation: 64695

$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.

Upvotes: 4

Claudiu
Claudiu

Reputation: 229561

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.

Upvotes: 1

Related Questions