Reputation: 4907
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
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
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