Javascript: Function expression over function declaration - javascript

I have two functions name init
One is declared using function declaration and another using function expression, like this:
function init() {
alert ('init 1');
}
var init = function(){
alert('init 2');
}
init();
When i call the init function it alerts init 2.
Demo
My question is:
1- Why javascript does not throw error as both functions have same name.
2- How can i call the first function?

Why javascript does not throw error as both functions have same name.
They don't have the same name. The second is a variable init containing an anonymous function. The first is a function named init.
You can test this by doing the following on both:
console.log(init.name);
You'll see that the first does indeed have a name init, whereas the second has no name.
How can i call the first function?
In this example the first can't be called after using init for your variable for the second. Unless you have another reference to the first like so:
function init() {
alert ('init 1');
}
var original = init;

Declarations in JavaScript are hoisted. A function declaration is one type of a declaration. Hence your program is equivalent to:
var init = function init() {
alert("init 1");
};
var init = function () {
alert("init 2");
};
init();
If you call init before your second definition then it would alert init 1:
function init() {
alert("init 1");
}
init();
var init = function () {
alert("init 2");
};
Because of hoisting you can even call init before it appears in the program:
init();
function init() {
alert("init 1");
}
var init = function () {
alert("init 2");
};
Just remember than no matter in what order they appear in the program, the function declaration always comes first:
init();
var init = function () {
alert("init 2");
};
function init() {
alert("init 1");
}
Hope that helps.

There is nothing fundamentally different between what you are doing and
var i = 1;
var i = 2;
No, JS does not throw an error, and no, once you've redefined i you can't get the old value back.
In ES6 and some modern browsers, you can say
const i = 1;
and then the engine will complain if it's redefined.

You can make kind of namespace:
var p1 = {
init: function() {
alert('init 1');
}
};
var p2 = {
init: function() {
alert('init 2');
}
};
var init = function() {
p1.init();
p2.init();
};
init();
Running ...

Javascript gets the last defination of function.
You can rename it unique or you can "use strict" to make it local function.
function functions(){
"use strict"
var init = function(){
console.log("b");
};
return {
start : init
}
};
var fn = new functions();
fn.start();

This works:
function init() {
alert ('init 1');
}
var init = (function(oldInit) { return function() {
oldInit(); // Call the first definition this way
alert('init 2');
}; })(init);
init();
The trick is to have the second init() remember the previous init. Javascript doesn't throw an error because it's often useful to redefine functions.

Related

IIFE, javascript, function undefined

This is my IIFE function
var test = function(){
console.log('fire');
}();
It invokes at start. But how do I call this again?
var fireTestFn = function(){
test();
}
fireTestFn(); // test() is not a function
JSbin https://jsbin.com/cesuzimogu/edit?js,console
You could return test from inside using a named function expression.
var test = function fn(){
console.log('fire');
return fn;
}();
The result of the IIFE will be assigned to test, which is obviously not a function, because you're not returning a function from the IFEE (or anything for that matter). Keep it simple; what you want is a named function you can call anytime as many times as you want:
function test() {
console.log('fire');
}
test(); // call as often as you want
Something like this will work
var myNamespace = {};
(function(ns) {
ns.test = function(){
console.log('fire');
};
/*ns.myOtherFunction = function(var1) { }*/
})(myNamespace);
var fireTestFn = function(){
myNamespace.test();
};
fireTestFn();
See example here: https://jsbin.com/helumoveqe/edit?js,console
As the error says
test() is not a function
When you self-invoked the function, the result was stored into test.
In order to be able to use test as a function and call repeatedly elsewhere, do not self-invoke
var test = function(){
console.log('fire');
};
or have the function return an inner function
var test = function () {
return function () {
console.log('fire');
}
};

Add function to object

I have the following code
var PROMO = PROMO || {};
PROMO.Base = (function () {
var _self = this;
var Init = function () {
WireEvents();
};
var WireEvents = function () {
//wire up events
};
} ());
In the same file I have the code to call the above function
I am trying to get to an end point where I can use the following code
$(document).ready(function () {
PROMO.Base.Init();
});
this gives the error
Cannot call method 'Init' of undefined
Now I know there are many ways to write javascript, but in this case I want to be able to call my functions, or least the Init method in the way shown above.
var PROMO = PROMO || {};
PROMO.Base = (function () {
var _self = this;
var Init = function () {
WireEvents();
};
var WireEvents = function () {
//wire up events
};
var reveal = {
Init: Init
};
return reveal;
} ());
You need to return the public facing functions. See updated code.
Working fiddle with both patterns, using IIFE and direct attribution.
Using var makes the definition private and your function is returning nothing. Use this:
PROMO.Base = {
Init: function() {
},
WireEvents: function() {
};
};
You are wrapping the definition with an IIFE(Immediately Executed Function Expression). So your PROMO.Base object will be assigned the value of that (function(){//blabla})(); returns. But your function doesn't have a return statement. By default it will return undefined.
Which is way your PROMO.Base will be undefined and you get this:
Cannot call method 'Init' of undefined
If you really want that IIFE:
var PROMO = PROMO || {};
// NEVER use _self = this inside static functions, it's very dangerous.
// Can also be very misleading, since the this object doesn't point to the same reference.
// It can be easily changed with Function.prototype.call and Function.prototype.apply
PROMO.Base = (function () {
_PROMO = {
Init : function () {
document.body.innerHTML += "itworks";
},
WireEvents : function () {
//wire up events
}
}
return _PROMO;
} ());
PROMO.Base.Init();
Update
The better and easier pattern is to simply assign the functions to PROMO.Base. Dully note you should not capitalize static functions, but only constructors. So if something is not meant to be instantiated, don't call it Init, it should be init. That is the convention.
var PROMO = {};
PROMO.Base = {};
PROMO.Base.init = function() {
console.log("this works");
};
PROMO.Base.wireEvents = function() {
console.log("this is a static function too");
};
You can attach it to the window object like ...
window.PROMO = (function($, _){
// this will access PROMO.Base
PROMO.Base = {
// inner functions here
Init:{}
};
})(jQuery, _);
Then load it as you do.
Or if you depend from jQuery
(function($){
var PROMO = {
// inner functions
Init: function(){},
WireEvents: function(){}
};
$.PROMO = PROMO;
})(jQuery);
On DOM ready
jQuery(function ($) {
var promo = $.PROMO || undefined;
promo.Base.Init();
});

Why would you assign a function to a variable instead of declaring a named function?

Why would I do this:
var myfunc = function() { /* code */ };
...
myfunc();
instead of this:
function myfunc() { /* code */ }
...
myfunc();
Are there any benefits of using one over the other? I have seen both examples used in different places.
The only difference as far as I can tell is that the anonymous function cannot call itself recursively while the named function can. There is a third type of construct that combines both of these, i.e. you can have a named function expression:
var myfunc = function myfunc() { /* code */ };
If a function is declarated normally, the function name (its identifier) will not be deleteable even if the identifier is redeclared. The identifier will only be deleted when its scope ends.
function myfunc() { /* code */ };
if (delete myfunc) { //will fail
alert('myfunc deleted');
} else {
alert('can not delete myfunc');
}
myfunc = null;
if (delete myfunc) { //will still fail
alert('myfunc deleted');
} else {
alert('can not delete myfunc');
}
var myfunc = null;
if (delete myfunc) { //will still fail
alert('myfunc deleted');
} else {
alert('can not delete myfunc');
}
But if a function declaration is assigned to a variable, its identifier can be deleted. This is especially useful when you need to create a global function but only use it temporarily, so that it can be deleted when it's no longer needed or to avoid possible identifier conflit with third party scripts.
var myfunc = function() { /* code */ };
if (delete myfunc) { //will succeed
alert('myfunc deleted');
} else {
alert('can not delete myfunc');
}
//or...
var myfunc = function myrealfunc() { /* code */ };
if (delete myfunc) { //will succeed
alert('myfunc deleted');
} else {
alert('can not delete myfunc');
}
There are a few differences, mostly pragmatic. When you 'var' a function, the normal assumption is some kind of 'locally' scoped function ( think a nested function ). When you do, function myFunction() {}, the function is mostly assumed to be globally scoped (though you could wrap this inside an anonymous function as well).
In the case of a javascript 'class', if you want to create a locally scoped function, you would have to use 'var' to declare it.
var myClass = function() {
var test = function() {
//This function has local scope
}
};
Adding to the above comments, this is a simple example.
var myVariable = resultFunction();
function resultFunction() {
return 1;
}
The above code will work. But you can't do the following
var myVariable = resultFunction();
var resultFunction = function() {
return 1;
};
But you can do
var resultFunction = function() {
return 1;
};
var myVariable = resultFunction();

Javascript call nested function

I have the following piece of code:
function initValidation()
{
// irrelevant code here
function validate(_block){
// code here
}
}
Is there any way I can call the validate() function outside the initValidation() function? I've tried calling validate() but I think it's only visible inside the parent function.
function initValidation()
{
// irrelevant code here
function validate(_block){
console.log( "test", _block );
}
initValidation.validate = validate;
}
initValidation();
initValidation.validate( "hello" );
//test hello
Hope that you are looking for something like this
function initValidation()
{
// irrelevant code here
this.validate = function(_block){
// code here
}
}
var fCall = new initValidation()
fCall.validate(param);
This will work.
Hope this addresses your problem.
You can call validate from within initValidation. Like this.
function initValidation()
{
// irrelevant code here
function validate(_block){
// code here
}
return validate(someVar);
}
validate is not visible to anything outside of initValidation because of its scope.
Edit: Here's my suggestion of a solution.
(function() {
function validate(_block){
// code here
}
function initValidation()
{
// irrelevant code here
return validate(someVar);
}
function otherFunctions() {
// ...
}
// initValidation = function
}());
// initValidation = undefined
All of your functions will be hidden to anything outside the function wrapper but can all see each other.
This invocation will return function statement, which is function validate.
So you can invoke directly after the first invocation.
function initValidation() {
// irrelevant code here
return function validate(_block) {
// code here
}
}
initValidation()();
I know this is an old post but if you wish to create a set of instances that you wish to work with that reuse the code you could do something like this:
"use strict";
// this is derived from several posts here on SO and ultimately John Resig
function makeClassStrict() {
var isInternal, instance;
var constructor = function(args) {
if (this instanceof constructor) {
if (typeof this.init == "function") {
this.init.apply(this, isInternal ? args : arguments);
}
} else {
isInternal = true;
instance = new constructor(arguments);
isInternal = false;
return instance;
}
};
return constructor;
}
var MyClass = makeClassStrict();// create "class"
MyClass.prototype.init = function(employeeName, isWorking) {
var defaultName = 'notbob';
this.name = employeeName ? employeeName : defaultName;
this.working = !!isWorking;
this.internalValidate = function() {
return {
"check": this.working,
"who": this.name
};
};
};
MyClass.prototype.getName = function() {
return this.name
};
MyClass.prototype.protoValidate = function() {
return {
"check": this.working,
"who": this.name
};
};
var instanceBob = MyClass("Bob", true);// create instance
var instanceFred = MyClass("Fred", false);// create instance
var mything = instanceFred.internalValidate();// call instance function
console.log(mything.check + ":" + mything.who);
var myBobthing = instanceBob.protoValidate();
console.log(myBobthing.check + ":" + myBobthing.who);
I know this thread's been here for quite some time but I thought I'd also leave my 0.02$ on how to call inner functions from outside their scope (might benefit somebody).
Note that in any place, a better design decision should be taken into consideration rather than some hackish workaround which will bite you back later.
How about using function expressions instead of function statements and making use of the global scope.
var innerFn;
function outerFn() {
innerFn = function(number) {
return number ** 2;
}
}
outerFn();
console.log(innerFn(5));
// if there's more complex code around and you could write this defensively
if (typeof innerFn !== 'undefined') {
console.log(`we are squaring the number 5 and the result is: ${innerFn(5)}`);
} else {
console.log('function is undefined');
}
Or, you can make use of closures:
function outer() {
// initialize some parameters, do a bunch of stuff
let x = 5, y = 10;
function inner() {
// keeps references alive to all arguments and parameters in all scopes it references
return `The arithmetic mean of the 2 numbers is: ${(x + y) / 2}`;
}
return inner;
}
innerFn = outer(); // get a reference to the inner function which you can call from outside
console.log(innerFn());
Create a variable outside the parent function, then in the parent function store your required function in the variable.
Var Store;
Function blah() {
Function needed() {
#
}
Store = needed;
}
As a minor variation of Esailija's answer, I did this:
function createTree(somearg) {
function validate(_block) {
console.log( "test", _block );
}
if (somearg==="validate") { return validate; } // for addNodes
// normal invocation code here
validate(somearg);
}
function addNodes() {
const validate = createTree("validate");
//...
validate( "hello" );
}
createTree("create");
addNodes();
//validate("illegal");
so validate() is now perfectly shared between createTree() and addNodes(), and perfectly invisible to the outside world.
Should work.
function initValudation() {
validate();
function validate() {
}
}
Function definition:
function initValidation() {
// code here
function validate(_block){
// code here
console.log(_block);
}
return validate;
}
Call it as below:
initValidation()("hello");
function initValidation()
{
function validate(_block){
console.log(_block)
// code here
}
// you have to call nested function
validate("Its Work")
}
// call initValidation function
initValidation()

Define an anonymous function as part of an object definition?

Suppose I have:
var myfunc = function() {
// do stuff
}
myfunc.foo = function() {
//do other stuff
};
Now myfunc has a property foo that is a function, great. Is there a way to create myfunc from the get-go in this state? That is, I want foo to be defined when myfunc is created. The syntax, I would imagine, is something like:
var myfunc = {
:function() {
// do stuff
},
foo: function() {
// do other stuff
}
}
Except that's wrong.
You can place an anonymous function inside an object, however the only plausible way of doing this is to call the anonymous function when the object is initialised, otherwise the function will never be able to be called - it's anonymous!
Here's a JSFiddle: http://jsfiddle.net/g105b/99K5F/
var myfunc = function() {
this.foo = function() {
console.log("myfunc.foo called!");
};
(function() {
console.log("Anonymous function called.");
})();
};
// Initialising "myfunc" will call the anonymous function.
var instance = new myfunc();
// Now the foo method can be called.
instance.foo();
A little confused as to what functionality you are looking to gain here...
If you want some code to execute when the myfunc is defined, you could use the module pattern:
var myfunc = (function() {
var self = {};
// any initialization code can go here
alert("myfunc init code");
self.somePublicMethod = function () {
}
return self;
}());
This can also be called an immediate function, a function that is defined and executed at the same time.
From within the closure, and code that is not defined as part of another function will be executed when the object is defined, so when you do something like this:
myfunc.somePublicMethod()
the alert would have already been fired.
(This answer written before the first half of the question was significantly revised)
Now myfunc has a property foo that is a function
No, it doesn't.
You called it with myfunc() so this is a reference to the global window object, thus you are creating window.foo.
Possibly what you are looking for is:
function myfunc () {
// do stuff when myfunc is called
}
myfunc.foo = function () {
// do stuff when myfunc.foo is called
};
or perhaps:
function myfunc () {
// do stuff when myfunc is instantiated
this.foo = function () {
// Add a foo property to this when myfunc is instantiated
// ... which is only worth while if you are doing pretty
// ... odd stuff with the variables that are passed in
}
}
var instance = new myfunc();
or maybe:
function myfunc () {
// do stuff when myfunc is instantiated
}
myfunc.prototype.foo = function () {
// Have a foo function on every instance of myfunc
}
var instance = new myfunc();
… but you've abstracted the problem you are trying to solve away in your question, so it is hard to tell what you are actually trying to achieve.
You can use jQuery:
var myFunc = jQuery.extend(
function() { ... },
{
bar: "wioll haven be",
foo: function() { alert(myFunc.bar); }
}
);
myFunc();
myFunc.foo();
This is mostly code acrobatics, this is probably the closest you'll get:
var myfunc;
(myfunc = function(){}).foo = function(){};
There is no practical difference in declaring methods later though, since javascript is single-threaded.

Categories