I've work with some framework & even wrote some libraries for my own purpose. I now working at implementation of an AngularJs router... And looked again at DI of angular:
[...String, Function]
function.$inject
For long I've been using the first syntax. Now while testing my router, I wanted to see the behaviour if it differs for both syntaxes and how to handle this, but...
First Hand
module.controller(function SampleController()
{
});
// Since it's and `invokelater...` function which is called right away,
SampleController.$inject = [/** my component dependencies **/]
See my face when I faced:
ReferenceError: SampleController is not defined
The Other Hand
I consider it unclean to write:
function SampleController()
{
}
SampleController.$inject = [];
moddule.$inject = [];
So Finally
I know it won't work. Why? - That's my question.
Why?
We have been taught that module, class, method/functions, some for loop, if...else create new scope.
Never have I read something like:
function's parameters are evaluated in their own scope
Please Tell Me
Thanks!
Named function expressions only create a matching variable in their own scope (which is useful for calling the function recursively).
They create nothing in the scope of the function that holds them.
When you pass it as a function argument, then the variable you pass it into is scoped to the function call. i.e. function function_you_pass_the_function_to(someFunction) { } scopes the someFunction variable to itself.
Related
I was experimenting to define the built-in method alert() to see what kind of error the console will throw, but instead the built-in alert() got overridden.
This is the code -
function alert(some_string) {
console.log(some_string+some_string);
}
function say() {
alert("Hello");
}
say();
The output is : HelloHello
Coming from a Java background, it would throw a compile error as :
error: method alert() is already defined
So what happened here? Did I actually override the method?
Overriding is a classical OO term which means that a child class has method with the same name as one of the classes it inherits from which is used instead of that method on the child class.
In this case, you are straight up taking the alert variable (which by default has a value of a function provided by the browser) and assigning it a new value (the function you just declared).
(That assumes you are working in the global scope. If you were in a local scope you would just be masking the variable so you would only be making alert inaccessible to other code in the same scope … and since you were writing that code too, it wouldn't be a problem because you would know if you needed the global alert and could avoid reusing its name.)
There might be hundreds of built-in functions and I might accidentally define a function with a same name as one of them, how can I check if such accidents don't happen?
There are two basic techniques for this.
Avoid creating globals
When you create a new variable, do it in as narrow a scope as possible. A common pattern is to use an IIFE to create a new scope for all the variables related to a given piece of code.
(function () {
"use strict";
function alert() {
// Locally scoped alert that doesn't get in the way
// of any variable called `alert` from the browser
// or another library
}
})();
Use namespaces
This is just a term for having a single global as the entry point to a bunch of related code. It is usually given an ALL_CAPS name that is unlikely to conflict with other code.
This allows the functions to be accessed from anywhere, like globals, without creating lots of global variables.
var MYLIBRARY;
(function () {
"use strict";
MYLIBRARY = {
alert: alert
};
function alert() { /* etc */ }
})();
I have a big code base of an Angular directive and I have been declaring functions like this:
$scope.doFoo = function() { ... };
because I thought Angular could manage/release the functions when required (not very sure where I read that).
Anyways, a contributor to my project told me he thinks this is not true. Is there any difference between declaring functions as scope variable or just declaring them as plain functions like this:
function doFoo() { ... };
Which one should I use?
With the former method, it's easy to clutter the scope with functions that may not be needed by the view (such as utility/helper functions inside the controller). I think it's logical to have a list of functions/variables used by the view at the top, assigned to the scope. Ie:
$scope.doFoo = doFoo;
Then, towards the bottom of the file, you can organize your functions. Ie:
function doFoo() { ... ]
Without doing $scope.doFoo, you will not be able to use doFoo in your template (such as <div ng-click="doFoo()">).
In this way, if doFoo() needed to use some helper function, you could have that declared somewhere in the controller and not clutter the scope by adding it.
I prefer using the controllerAs syntax, and binding vm to this, but that's a different story all together. (Can read about that style preference here.)
Zack Tanner's answer is correct (and succinct!), but here's some supplementary information that may also help you out.
First, here are some terms we can agree on:
function Declaration
function doFoo() {
//...
}
This declares a function inside of the current function scope (closure)
function Expression
$scope.doFoo = function() {
//...
}
This declares a function as belonging to an object
So what's the difference and why should you care? Here's Zack Tanner's explanation in action:
angular.module("myModule").controller(["$scope", function($scope) {
var self = this;
$scope.doFoo = doFoo;
$scope.doBar = doBar;
////Implementation////
function doFoo() {
// do foo stuff
}
function doBar() {
// do bar stuff
}
}]);
First of all, this is probably blatantly (and rightfully) stolen from the wisdom that comes of programming in C/C++ or John Papa. In either case, the reason this works (and would even work if you put a return before the comment in the controller) is because of Function Hoisting. Basically, it comes down to a simple rule: Function Declarations will always be "hoisted" to the top of the scope they are declared in. The same is actually true for variables, too!
To answer your question directly, I don't know about Angular's ability to release or manage functions (I doubt it does?), but it does pay in this case to declare your functions and assign them to your $scope. Also, "controller as" syntax is indeed awesome, so consider using that if possible (no $scope, plus no weirdness with the prototype chain!).
tl;dr use function doFoo() { //... }
Any functions (methods?) bound to $scope or a controller (via controllerAs) will be available on the view they are attached to. Functions named in a more traditional way function doFoo() { ... } will only be accessible in their respective (lexical) scopes (be that a controller, service, directive, etc.). Basically, $scope allows you to use your functions outside of its lexical scope (to clarify, $scope is an object that is available outside the lexical scope of the controller/directive, just like declaring functions inside a service, you can't use them elsewhere unless you attach them to a returned object).
Each have their place in an application, it's really up to how you want to use the function.
Yes there's a reasonable difference , you only need to bind functions to scope that are used within the views. There is no need to pollute scope with things that are never used in views.
A common style guide best practice is also to declare functions below scope declarations to make it easier to review what is contained within the scope easier
Example:
// show all the scope related stuff at top of component
$scope.foo = foo;// reference to function below
// all the business stuff at bottom of component
function foo(){}//used in view
function bar(){} // only used as utility in controller
Good reference: John Papa Angular style guide
Today while working my mind was stack at some point in javascript.
I want to know that what is basic difference between
function FunctionName(){
//Code goes here;
}
And
var MyFuncCollection = new Object();
MyFuncCollection.FunctionName = function(){
//Code goes here;
}
Both are working same. Then what is difference between then. Is there any advantage to use function with object name?
I have read Question. But it uses variable and assign function specific variable. I want to create object and assign multiple function in single object.
The first one defines a global function name. If you load two libraries, and they both try to define FunctionName, they'll conflict with each other. You'll only get the one that was defined last.
The second one just has a single global variable, MyFuncCollection. All the functions are defined as properties within that variable. So if you have two collections that try to define the same function name, one will be FuncCollection1.FunctionName, the other will be FuncCollection2.FunctionName, and there won't be any conflict.
The only conflict would be if two collections both tried to use the same name for the collection itself, which is less likely. But this isn't totally unheard of: there are a few libraries that try to use $ as their main identifier. jQuery is the most prominent, and it provides jQuery.noConflict() to remove its $ binding and revert to the previous binding.
The short answer is, the method in object context uses the Parent Objects Context, while the "global" function has its own object context.
The long answer involves the general object-oriented approach of JavaScript, though everything in JavaScript is an object you may also create arrays with this Method.
I can't really tell you why, but in my experience the best function definition is neither of the top mentioned, but:
var myFunction = function(){};
It is possible to assign function to variables, and you may even write a definition like this:
MyObject.myMethod = function(){};
For further reading there are various online Textbooks which can give you more and deeper Information about this topic.
One main advantage I always find is cleaner code with less chance of overwriting functions. However it is much more than that.
Your scope changes completely inside the object. Consider the following code ::
Function:
function FunctionName(){
return this;
}
FunctionName()
Returns:
Window {top: Window, location: Location, document: document, window: Window, external: Object…}
Object:
var MyFuncCollection = new Object();
MyFuncCollection.FunctionName = function(){
return this;
}
MyFuncCollection.FunctionName()
Returns:
Object {}
This leads to some nice ability to daisy chain functions, amongst other things.
The first:
function functionName (){
//Code goes here;
}
Is a function declaration. It defines a function object in the context it's written in.
Notice: this doesn't have to be the global context and it doesn't say anything about the value of this inside it when it's invoked. More about scopes in JavaScript.
Second note: in most style guides functions are declared with a capitalized name only if it's a constructor.
The second:
var myFuncCollection = {};
myFuncCollection.functionName = function () {
//Code goes here;
};
notice: don't use the new Object() syntax, it's considered bad practice to use new with anything other then function constructors. Use the literal form instead (as above).
Is a simple assignment of a function expression to a property of an Object.
Again the same notice should be stated: this says nothing about the value of this when it's invoked.
this in JavaScript is given a value when the function object is invoked, see here for details.
Of course, placing a function on an Object help avoiding naming collisions with other variables/function declarations in the same context, but this could be a local context of a function, and not necessarily the global context.
Other then these differences, from the language point of view, there's no difference whatsoever about using a bunch of function declarations or an Object with bunch of methods on it.
From a design point of view, putting methods on an Object allows you to group and/or encapsulate logic to a specific object that should contain it. This is the part of the meaning of the Object Oriented Programming paradigm.
It's also good to do that when you wish to export or simply pass all these functions to another separate module.
And that's about it (:
I'm new to JavaScript, and have a simple (I presume) question regarding best practices for accessing variables in functions:
When should I declare a global variable, as opposed to simple passing a value into a function?
Declaring a global variable should only be used as an option of last resort.
Global variables are bad in general and especially so in javascript. There is simply no way to prevent another piece of javascript from clobbering your global. The clobbering will happen silently and lead to runtime errors.
Take the following as an example.
// Your code
myParam = { prop: 42 };
function operateOnMyParam() {
console.log(myParam.prop);
}
Here i've declared 2 global variables
myParam
operateOnMyParam
This might work fine while testing your javascript in isolation. However what happens if after testing a user combines your javascript library with my javascript library that happens to have the following definitions
// My code
function myParam() {
console.log("...");
}
This also defines a global value named myParam which clashes with your myParam. Which one wins depends on the order in which the scripts were imported. But either way one of us is in trouble because one of our global objects is dead.
There are many, many reasons.. but an easy one is.. The argument of a function only exists in the function, while it's running. A global variable exists all the time, which means:
it takes up memory until you manually 'destroy' it
Every global variable name needs to be unique
If, within your function.. you call another function.. which ends up calling the first function, all of a sudden you may get unexpected results.
In short: because the function argument only lives for a really short time and does not exist outside the function, it's much easier to understand what's going on, and reduced the risk of bugs greatly.
When dealing with framework-less JavaScript I'll store my simple variables and functions in an object literal as to not clutter up the global namespace.
var myObject = {
variableA : "Foo",
variableB : "Bar",
functionA : function(){
//do something
//access local variables
this.variableA
}
}
//call functions and variables
myObject.variableA;
myObject.functionA();
I have some third-party Javascript that has statements like this:
FOO = function() {
...functions() ...
return { hash }
}();
It is working as designed but I'm confused by it. Can anybody define what this structure is doing? Is it just a weird way to create a class?
This is a technique that uses closure. The idiom is well-known, but confusing when you first see it. FOO is defined as the object that the outermost function() returns. Notice the parenthesis at the end, which causes the function to evaluate and return { hash }.
The code is equivalent to
function bar() {
...functions() ...
return { hash }
};
FOO = bar();
So FOO is equal to { hash }. The advantage of this is that hash, whatever it is, has access to stuff defined inside the function(). Nobody else has access, so that stuff is essentially private.
Google 'Javascript closure' to learn more.
Js doesn't really have classes, per se, but "prototypes". This means that no two objects are ever of the same "type" in the normal type-safe sense, and you can dynamically add members to one instance while leaving the other unmolested. (which is what they have done).
Believe it or not, the syntax they have used is probably the most lucid, as it doesn't try to hide behind some C-style class syntax.
Doug Crockford's Javascript: The Good Parts is a quick read, and the best introduction to OOP in js that I've come across.
That's not actually a class, just an object. I'd recommend reading this: http://javascript.crockford.com/survey.html
Because JavaScript doesn't have block scope, your choice is (mostly) to have all variable reside in global or function scope. The author of your snippet wants to declare some local variables that he doesn't want to be in the global scope, so he declares an anonymous function and executes it immediately, returning the object he was trying to create. That way all the vars will be in the function's scope.
The parans at the end make this the Module Pattern, which is basically a way to have a single instance of an object(Singleton) while also using private variables and functions.
Since there's closures hash, if it's itself an object or function, will have access to all variables declared within that anonymous Singleton object.
You're missing an open parens, but it is basically a way of usually hiding information within an object i.e. a way of setting up private and privelaged methods.
For example
var foo = (function() {
/* function declarations */
return { /* expose only those functions you
want to expose in a returned object
*/
}
})();
Take a look at Papa Crockford's Private Members in JavaScript. This is basically the pattern you are seeing, but in a slightly different guise. The function declarations are wrapped in a self-invoking anonymous function - an anonymous function that is executed as soon as it's declared. Since the functions inside of it are scoped to the anonymous function, they will be unreachable after the anonymous function has executed unless they are exposed through a closure created by referencing them in the object returned from the execution of the anonymous function.
It's generally referred to as the Module Pattern.