Is it possible for javascript to break IIFE from another function? - javascript

Please see this example code:
(function() {
if (1 + 1 === 2) {
return;
}
console.log(`This Line Won't Compile`);
})()
The code above simply breaks when the condition is true.
However, I would like to extract the whole logic outside of this IIFE.
function checkNumber() {
if (1 + 1 === 2) {
return;
}
}
(function() {
checkNumber(); // How do I achieve this?
console.log(`This Line Now Compile, but I don't want this line compile.`);
})()
How do I achieve this?
Is it possible to achieve this?

You need a flag if the function take short circuit. In this case you need another check and return early.
function checkNumber() {
if (1 + 1 === 2) {
return true; // supply a flag
}
}
void function() {
console.log('IIFE');
if (checkNumber()) return; // use this flag
console.log(`This Line Now Compile, but I don't want this line compile.`);
}();

There are many options, a simple one would be to set a global variable which you can then use in the IIFE
var iAmAGlobalVariableKnowingWhatToDo = false;
var checkNumber = function () {
if (1 + 1 === 2) {
iAmAGlobalVariableKnowingWhatToDo = true;
return;
}
iAmAGlobalVariableKnowingWhatToDo = false;
};
// note everything until this line of code is in the global scope!
// that's why you can use the checkNumber() and the variable inside the IIFE
(function() {
checkNumber();
if(iAmAGlobalVariableKnowingWhatToDo) {
return;
}
console.log(`This Line Now Compile, but I don't want this line compile.`);
})()

Related

Javascript: conditional variable initialization in if/else

I'm initializing a variable conditionally with if/else. I want to follow functional programming rules.
My eg.:
if (1 === 2) {
const a = false;
} else {
const a = true;
}
console.log(a);
Linter say: ESLint: 'a' is not defined.(no-undef).
As you know there is no way that a would not be defined. Another approach could be:
const a = 1 === 2 ? false : true;
But what if there were three conditions in if/else? How do I achieve that and avoid error?
That's why I always use var. But for your example you can have define const a using a function or a intermediate variable.
const a = init_a()
function init_a() {
if (1 == 2) {
return 1;
} else {
return 2;
}
}
console.log(a)
You need to define your variable in a scope that you can access and print.
You can use something more elegant like this:
const a = (1 ==2) ? 'A' : 'B'
console.log(a)
For more info check What is the scope of variables in JavaScript?
You can use an IIFE (Immediately Invoked Function Expression) if you want to stick to functional programming style.
This is especially useful when dealing with multi-level if and switch statements:
const a = (() => {
if (1 === 1) {
return 'first'
} else if (1 === 2) {
return 'second'
} else {
return 'third'
}
})()
// 'first'
console.log(a)

Reducing function name usage within function

When I search for a function name - it gets clumsy when I see plenty of function names as in the example. In large code base I waste my time when searching for how and from where a function has been called :
function do_something()
{
if (typeof do_something.flag == "undefined")
{
do_something.flag = true;
}
if (do_something.flag == null)
{
do_something.flag = true;
}
}
Here when I search for do_something so that I can look from where it is called instead I find plenty of lines consisting of do_something.flag1,do_something.flag2 and so on which isn't of any use in most of such searches. In large function I get plenty of such lines occupying search output.
I've another scenario. In (Netbeans) IDE I want to do Ctrl-F do_something function looking for where it is called in the file. Now I find pressing F3 within the function itself iterating over it's own lines containing something like do_something.var1=5 etc.
In short is there any way to reduce the function name usage within the function when creating object-global variables?
I've much longer functions but I'll give real example of medium level function causing this problem:
function slow_down_clicks(label, userfunc, timeinmsec)
{
console.log("slow_down_clicks=" + label);
if (typeof slow_down_clicks.myobj == UNDEFINED)
{
slow_down_clicks.myobj = {};
}
if (typeof slow_down_clicks.myobj[label] == UNDEFINED)
{
slow_down_clicks.myobj[label] = {
inqueue: false,
lastclickedtime: 0,
login_post_error_count: 0
};
}
var myfunc = function ()
{
console.log("Executing the user func");
slow_down_clicks.myobj[label].inqueue = false;
slow_down_clicks.myobj[label].lastclickedtime = new Date().getTime();
userfunc();
}
console.log("Due to error in home.aspx reloading it", ++slow_down_clicks.myobj[label].login_post_error_count);
if (slow_down_clicks.myobj[label].inqueue == false)
{
var diff = new Date().getTime() - slow_down_clicks.myobj[label].lastclickedtime;
console.log("diff=", diff, timeinmsec);
if (diff > timeinmsec)
{
myfunc(); //click login
}
else
{
console.log("queuing the request after:", timeinmsec - diff);
slow_down_clicks.myobj[label].inqueue = true;
setTimeout(function ()
{
console.log("called myfunc babalatec");
myfunc();
}, timeinmsec - diff);
}
}
else
{
console.log("Discarding this request...");
}
}
I think you can just define the fields as normal variables and put your code in its own file. Then you can just refer to the variables by its name inside your function because they are within the function's closure. The variables will not be accessible outside because you limit them in its own file.
like:
let flag = false
function doSomething () {
if (!flag) {
flag = true
}
....
}
Put the above code snippet in a separate file and import the function when you want to use it.

JS "as soon as" condition

I've got a small problem (kind of a problem with curiosity actually). Is it possible to create some condition when if the condition is satisfied, the appropriate code is executed? Without use of setInterval and setTimeout of course. Or callback? Maybe AJAX?
var x;
if (x != "undefined") {
//code to be executed
}
setTimeout(function() { x = 3.14; }, 5000);
//after those let's say 5 seconds (the time is random) x becomes defined and the code above is executed
Thanks!
If you're ok with wrapping x inside an object, you can try using setter pattern:
var obj = {};
Object.defineProperty(obj, 'x', { set: function(xval) { /* do stuff; */ } });
// some time later in the code ...
obj.x = somevalue
// do stuff will fire
Or, in the object initializer:
var obj = {
set x(xval) {
// do stuff;
}
}
// some time later in the code...
obj.x = somevalue
// do stuff will fire
Note that the only (but optional) value we can explicitly pass to the callback is the value we set the bound property to (the value of x). (Of course, you can reference anything that obj's scope can see).
See also: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/set
when a function depends on another one, I just do a simple callback.
var x;
function check_and_wait(callback) {
if (x != undefined) {
callback();
}
}
check_and_wait(function() {
//code goes here
});
A possible solution using promises:
var x;
var promise = new Promise(function(resolve,reject) {
setTimeout(function() {
x = 3.15;
resolve();
},3000)
});
promise.then(function(){
console.log("code to be executed")
console.log(x)
});

Do code if this code runs

I want to run code if another code snippet has run.
IF this code runs
(function() {
// Code runs here
})();
THEN run this code also
//This code
Example
if (condition) {
block of code to be executed if the condition is true
}
http://www.w3schools.com/js/js_if_else.asp
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Statements/if...else
This won't seem to work?
if ((function() {// Code runs here})();)
{
//This code
}
You should use return statement otherwise the IIFE would return undefined and thus it would be equivalent to false statement.
if (
(function() {
// Code runs here
return true;
})();
){
//This code
}
Use this
var functionName = (function() {
var didRun = false;
// This function will be executed only once, no matter how many times
// it is called.
function functionName() {
// Your code goes here
}
return function() {
if (didRun) {
return;
}
didRun = true;
return foo.apply(this, arguments);
}
})();
and check, when the function didRun, then execute your core
The IIFE seems superfluous to me here - just use a named function the simple way and keep it straightforward. If anyone can give me a use for the IIFE as the conditional expression in an If ... else, please comment - I would love to understand what I might be missing:
function odd(num) {
return num % 2;
}
// Use Dev Tools Console (F12) to see output
function logOddEven(num) {
if (odd(num)) {
console.log(num + ' is odd');
} else {
console.log(num + ' is even');
}
}
logOddEven(0);
logOddEven(1);
logOddEven(2);

best way to toggle between functions in javascript?

I see different topics about the toggle function in jquery, but what is now really the best way to toggle between functions?
Is there maybe some way to do it so i don't have to garbage collect all my toggle scripts?
Some of the examples are:
var first=true;
function toggle() {
if(first) {
first= false;
// function 1
}
else {
first=true;
// function 2
}
}
And
var first=true;
function toggle() {
if(first) {
// function 1
}
else {
// function 2
}
first = !first;
}
And
var first=true;
function toggle() {
(first) ? function_1() : function_2();
first != first;
}
function function_1(){}
function function_2(){}
return an new function
var foo = (function(){
var condition
, body
body = function () {
if(condition){
//thing here
} else {
//other things here
}
}
return body
}())`
Best really depends on the criteria your application demands. This might not be the best way to this is certainly a cute way to do it:
function toggler(a, b) {
var current;
return function() {
current = current === a ? b : a;
current();
}
}
var myToggle = toggler(function_1, function_2);
myToggle(); // executes function_1
myToggle(); // executes function_2
myToggle(); // executes function_1
It's an old question but i'd like to contribute too..
Sometimes in large project i have allot of toggle scripts and use global variables to determine if it is toggled or not. So those variables needs to garbage collect for organizing variables, like if i maybe use the same variable name somehow or things like that
You could try something like this..: (using your first example)
function toggle() {
var self = arguments.callee;
if (self.first === true) {
self.first = false;
// function 1
}
else {
self.first = true;
// function 2
}
}
Without a global variable. I just added the property first to the function scope.
This way can be used the same property name for other toggle functions too.
Warning: arguments.callee is forbidden in 'strict mode'
Otherwise you may directly assign the first property to the function using directly the function name
function toggle() {
if (toggle.first === true) {
toggle.first = false;
// function 1
}
else {
toggle.first = true;
// function 2
}
}

Categories