Assign and execute Javascript function simultaneously - javascript

Is there a more elegant way of writing something like this, where myFunction is asigned to the function func but func is also executed during the assignment?
var myFunction = (function(){
var func = function(){
console.log('hello world');
};
func();
return func;
})();
...
myFunction();

var myFunction = (function func(){
console.log('hello world');
return func;
})();
You can name your anonymous function. This name will only be accessible inside of the function itself, though.

Your core statement is this
var <name> = (<functionExpression>)();
I don't see how this could be more elegant.

Assignments expressions return the assigned value, but you have to declare the variable separately so you still have to repeat the identifier:
var outer;
(outer = function() {
var inner;
return (inner = function() {
print('hello world');
})(), inner;
})();
outer();
That said if I saw this code from a coworker I'd whap him with a rolled up newspaper.

Related

Defining a class in JavaScript? [duplicate]

This question already has answers here:
What is the (function() { } )() construct in JavaScript?
(28 answers)
Closed 4 years ago.
I was following a tutorial where they used a translator to translate a class in Typescript into javascript. The translated javascript is a bit confusing and I was wondering if someone can explain to me what the code is doing.
Original Typescript:
class Greeter {
greeting: string;
constructor(message: string){
this.greeting;
}
greet(){
return "Hello, " + this.greeting;
}
}
and the translated Javascript:
var Greeter = (function(){
function Greeter(message){
this.greeting = message;
}
Greeter.prototype.greet = function(){
return "Hello, " + this.greeting;
};
return Greeter;
}());
I am confused about this part (function() { ... }());
what is the first () doing? why is the function(){} necessary? and what is the following () doing?
The syntax is pretty confusing and I hope someone can explain this.
I am confused about this part (function() { ... }());
IIFE this function will executed as soon as it is interpreted by the browser. You don't have to explicitly call this function.
what is the first () doing? why is the function(){} necessary?
All functions in javascript are Object by nature. To create a instance of it you have to call like new Greeter() so the context this is set properly. If executed like Greeter() now the context this is from where it's executed. In most cases it's the window object.
Reference articles
https://www.phpied.com/3-ways-to-define-a-javascript-class/
https://medium.com/tech-tajawal/javascript-classes-under-the-hood-6b26d2667677
That's called IIFE.
General syntax:
(function () {
statements
})();
But sometimes, you can write:
(function () {
statements
}());
I usually use the second's because it's following these steps:
Defining a function: function () { /* statements */ }
Calling the function: function () { /* statements */ }()
And wrapping the function: (function () { /* statements */ }())
Or use it with as an asynchronous thread:
(async function () {
// await some task...
})();
(async () => {
// await some task...
})();
You can also use it to define some local variable(s), like this:
let Person = (function () {
let _name = null;
class Person {
constructor(name) {
_name = name;
}
getName() {
return _name;
}
}
return Person;
}());
let person = new Person('Harry');
console.log(person.getName());
console.log(window._name);
For modules, you want to create some plugin(s) and make it to be global, you can write:
(function (global, factory) {
// we can use "global" as "window" object here...
// factory is a function, when we run it, it return "Person" class
// try to make it global:
global.Person = factory(); // same to: window.Person = factory();
}(window, function () {
class Person {};
return Person;
}));
This construct:
const foo = (function() { })();
Creates an anonymous function, and immediately calls it. The result gets places into foo.
It's possible to split this up in more lines with an extra variable:
const temp = function() { };
const foo = temp();
The reason typescript does this, is because placing code in function creates its own new scope. This makes it possible to do certain things without changing the global namespace.
(function() { ... }()); is a form of IIFE (Immediately Invoked Function Expression)
For example:
var Greeter = (function(){
return 1;
}());
The result is equal to
function fn() {
return 1;
}
var Greeter = fn();
The value of Greeter is 1 after executing the above codes. But the former one uses anonymous function and the latter one declared a variable fn to store the function.
Greeter.prototype.greet = function(){
return "Hello, " + this.greeting;
};
This code snippet is to define a function on the prototype of object Greeter so that this function can be inherited when you create new Greeter(). You may refer to Object.prototype

How access to variables within an anonymous function?

I have an anonymous function inside a variable GLOBAL.
var GLOBAL = function (){
var func1 = function(){
console.log("function 1 go!")
}
var func2 = function(){
console.log("function 2 go!")
}
return {
init: function(){
func1();
}
}
}()
In my init function return func1, calling it so GLOBAL.init();.
My question is: how I can call functions directly for example GLOBAL.func1() or GLOBAL.func2().
You have to return the function references,
var GLOBAL = function (){
var func1 = function(){
console.log("function 1 go!");
}
var func2 = function(){
console.log("function 2 go!")
}
return { func1,func2 };
}();
Now you can access it like GLOBAL.func1() and GLOBAL.func2(). And do not confuse with the syntax { func1,func2 };. That is quite similar to { func1 : func1,func2 : func2 }; I just used the shorthand introduced in ES6.
You can't. They are locally scoped variables. Being inaccessible outside the function is a large part of the point.
If you want them to be accessible, then you need to make them so explicitly (as you have done for the anonymous function you assign to init).
You should explicit add those functions in the returned object. In this code you can still continue executing init() as a object initialization.
var GLOBAL = function (){
var func1 = function(){
console.log("function 1 go!")
};
var func2 = function(){
console.log("function 2 go!")
}
return {
init: function(){
this.func1();
},
func1,
func2
}
}();
GLOBAL.func1();
GLOBAL.func2();
I hope that helps :D
You can follow modular approach if it can help:
var GLOBAL = {
func1: function(){
console.log("function 1 go!")
},
func2: function(){
console.log("function 2 go!")
}
}
GLOBAL.func1();
GLOBAL.func2();

jquery nested function access

How can I access the test2() function outer either in onclick , as shown in the plain function, wrapped in parenthesis to tell the runtime to return the function to the parent scope, once it's returned the function is executed using line 4, maybe reading through these steps will help.
<p onclick='test().test2()'> some text </p>;
<script>
//the below declaration will not change
var jQuery = 'Hi';
(function ($) {
function test(){
function test2(){
alert('text')
}
alert($)
}
console.log($);
test().test2()
})(jQuery)
</script>
You can only access test2 if you declare the function in the same scope as where you want the to access the function. In this case it means you need to declare the function in the outer scope.
You can do so by setting a variable in the outer scope like this:
var test2;
var jQuery = 'Hi';
(function ($) {
function test(){
test2 = function(){
alert('text')
}
alert($)
}
console.log($);
test(); //test needs to be called first to define test2.
test2();
})(jQuery)
I checked twice and this works:
var jQuery = 'Hi';
window.test = (function ($) {
function test(){
this.test2 = function () {
alert('text')
};
alert($);
return this;
}
console.log($);
test().test2();
return test;
})(jQuery);

Is It Possible To Call A JavaScript Function Inside An Immediately-Invoked Function Expression

I'm using jQuery and have a function wrapped inside an immediately-invoked function expression like so:
<script type="text/javascript" src="jquery-1.8.3.min.js"></script>
<script type="text/javascript">
(function ($) {
var message = 'x called';
function x() {
alert(message);
}
})(jQuery);
x();
</script>
This will result is an error since the function "x" is not defined outside the immediately-invoked function expression. Is there any way to call the function "x" outside the immediately-invoked function expression?
Only if you expose the function in some way. For example, you can return it from the outer function:
var x = (function ($) {
var message = 'x called';
function x() {
alert(message);
}
return x;
})(jQuery);
x();
Or, similarly, you can return it on an object:
var obj = (function ($) {
var message = 'x called';
function x() {
alert(message);
}
return {"x": x};
})(jQuery);
obj.x();
Functions and variables declared inside of a function are not directly reachable from outside of that function, unless you provide some means of accessing them by returning something, or giving a reference to a variable declared outside of that function.
Make a namespace for other classes or functions you might want to do this with. You don't want to continually pollute the global namespace but there's no reason you can't make one namespace that's global and put your individual things underneath that:
(function($){
window.MyNamespace = function(){};
var message = "Something here";
$.extend(MyNamespace, {
x: function(){
alert(message);
}
});
})(jQuery)
MyNamespace.x()
You can change your code as follows:
<script type="text/javascript" src="jquery-1.8.3.min.js"></script>
<script type="text/javascript">
var x;
(function ($) {
var message = 'x called';
x = function () {
alert(message);
}
})(jQuery);
x();
</script>
jsFiddle link for this: http://jsfiddle.net/aLnbn/
Yes, ( one way is to: )just return it from the IIFE using a return statement, also you need to "catch" the return by assigning a variable to the IIFE
var foo = (function(){
return your_function;
}());
You can access your method by using your IIFE to return (or augment) a global variable.
You might do it like this:
var globalObject = (function (theObject, $) {
if (theObject.theMethod) {
return theObject;
}
var message = 'theMethod called';
theObject.theMethod = function () {
alert(message);
};
return theObject;
})(globalObject || {}, jQuery);
globalObject.theMethod();
The pattern we use is slightly better.
We have one global object (ie namespace) and we add modules to it by importing js files that contain IIFE's.
Each IIFE adds a new module to a single global object.
This makes it so our entire project has only one global object that can optionally utilize any of our modules by including a file.
I recommend checking out this article, which is a good discussion on the JavaScript module pattern:
http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth
Try this:
var miFunc = (function($) {
var message = 'x called';
function x() {
console.log(message);
}
this.x = x;
return this;
})(jQuery);
miFunc.x();
Test: http://jsbin.com/erucix/2/edit
One of the purposes of a closure is to limit scope. That is why x() is defined and can be called inside of your immediately-invoked function expression but is undefined outside.
To have your code work without refactoring, you can take advantage of JS grammar which differentiates between a function statement and a function operator. Both are semantically identical but the latter can be assigned to a variable which works just right for your scenario:
var x; //scoped *outside* of the closure
(function ($) {
var message = 'x called';
x = function() {
alert(message);
}
})(jQuery);
x(); //alerts 'x called'
You can access your method by using your IIFE to return a global variable.
//IIFEs - Immediately Invoked Function Expressions
var namespaceTestIIFE = (function ($) {
/** Public functions and state. */
var pub = {};
$(document).ready(function () {
//your on ready logic
});
pub.testAlert = function () {
alert('Hello TestAlert');
}
return pub;
})(jQuery);
OR
var compareForm = (function ()
{
/** Public functions and state. */
var pub = {};
pub.testAlert = function () {
alert('Hello TestAlert');
}
return pub;
}());
To access function use "namespace.functionname" for example -
namespaceTestIIFE.testAlert();

javascript - shortcut for calling a function at the same time it is defined

to call a function at the same time it's defined, i had been using:
var newfunc = function() {
alert('hi');
};
newfunc();
is the following the correct way of combining these 2:
var newfunc = function() {
alert('hi');
}();
There could be a number of reasons you wish to do this. I'm not sure what yours are, but let me introduce a couple of favourite patterns:
Pattern #1: A singleton. The function is executed and then becomes a singleton object for use by other components of your code.
var singletonObject = new function() {
// example private variables and functions
var variable1 = {};
var variable2 = {};
var privateFunction = function() {
};
// example public functions
this.getData = function() {
return privateFunction(variable1, variable2);
};
// example initialisation code that will only run once
variable1.isInitialised = true;
};
Pattern #2: Self-executing anonymous function ... handy for sooo many reasons!
// Declare an anonymous function body.
// Wrap it in parenthesis to make it an "expression.
// Execute it by adding "();"
(function(){})();
And here's an example that also creates a namespace for your objects.
I'm using "NS" as an example namespace:
// declare the anonymous function, this time passing in some parameters
(function($, NS) {
// do whatever you like here
// execute the function, passing in the required parameters.
// note that the "NS" namespace is created if it doesn't already exist
})(jQuery, (window.NS = window.NS || {}));
You can also set the context of a self-executing function by using .call or .apply instead of the usual parenthesis, like this:
(function($){
// 'this' now refers to the window.NS object
}).call(window.NS = window.NS || {}, jQuery);
or
(function($){
// 'this' now refers to the window.NS object
}).apply(window.NS = window.NS || {}, [jQuery]);
var newfunc = function f() {
alert("hi!");
return f;
}();
Having a named function expressions allows the function to recursively call itself or, in this case, return itself. This function will always return itself, however, which might be an annoyance.
No. Your second example will immediately call the anonymous function and assign its return value to newfunc.
adamse describes an approach which appears to work. I'd still avoid the approach as the two step process is easier to read and thus will be easier to maintain.
If I understand your question correctly, give this a try:
(f = function (msg) {
msg = msg ? msg : 'default value';
alert(msg); }
)();
f('I\'m not the default value!');
You'll get two alerts, the first one will say "default value" and the second will say "I'm not the default value. You can see it in action at jsBin. Click 'preview' to make it run.
you could do like this:
o = {};
o.newfunc = ( function() {
function f() {
alert('hi');
}
f();
return {
f : f
};
}
)();
then calling the function like:
o.newfunc.f();
will also render an alert message

Categories

Resources