best way to toggle between functions in javascript? - 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
}
}

Related

reduce complexity of if elseif conditions

I have one function which is having if elseif conditions and the cyclomatic complexity is approaching 5. How do I reduce it?
function testFunc() {
var step = getModel('step');
if(step === 1) {
this.resetTask(); //calling some function
this.updateStep(0);
return true;
} else if(step === 2) {
this.initTask; //some other function
return true;
} else if(step === 3) {
this.name === 'add' ? this.add() : this.edit();
return true;
}
return false;
}
tried replacing with switch case but it didn't help.
Very simple refactor - remove all conditional logic you have now and extract each piece as a separate function into a map. Since you only execute one branch each time, depending on step, you can make that value the key and fetch what needs to be executed. You can then provide a fallback for when there is nothing that corresponds to step.
Now the cyclomatic complexity is 2, since there is only one place the code branches - either you find the corresponding handler for step or not. Also, the branching in step 3 is a completely separate function now, thus it doesn't need to count as part of testFunc
function testFunc() {
var step = getModel('step');
var steps = {
1: function() {
this.editTask(); //calling some function
this.updateStep(0);
return true;
},
2: function() {
this.initTask; //some other function
return true;
},
3: function() {
this.name === 'add' ? this.add() : this.edit();
return true;
},
default: function() {
return false;
}
};
var fn = steps[step] || steps.default;
return fn();
}
This will reduce your code complexity and makes more readable.
You can decouple your condition into multiple function and attach that function in condition object. here I'm passing this in argument but you can use different approch. here I've also given value of this just for the shake of running example. copy and paste in your editor and try.
function meaningfulFuncName1() {
this.editTask(); //calling some function
this.updateStep(0);
return true;
}
function meaningfulFuncName2() {
this.initTask; //some other function
return true;
}
function meaningfulFuncName3(context) {
context.name === 'add' ? context.add() : context.edit();
return true;
}
function defaultCase() {
return false;
}
function testFunc() {
this.name = 'add'
const step = getModel('step')
conditionObject = {
1: meaningfulFuncName1,
2: meaningfulFuncName2,
3: meaningfulFuncName3,
default: defaultCase
}
return conditionObject[step](this);
}
To me, changing it like this makes it less complex to understand. Although to some will be less readable. Also it is a little faster.
function testFunc() {
var step = getModel('step');
if(step==1){this.editTask(); this.updateStep(0); return true;}
if(step==2){this.initTask; return true;}
if(step==3){this.name==='add' ? this.add() : this.edit();return true;}
return false;
}

Terminate a function whenever it is executed - Javascript

How do I stop a function from further execution ? Answers to my this question didn't fulfill my need of stopping/terminating a function from further execution.
I have this kind of hierarchy of Constructor functions :
//First Constructor function
function Foo() {
this.foo1 = async function() {
alert("Foo 1 hs bee called");
return true;
}
this.foo2 = async function() {
alert("Foo 2 hs bee called");
return true;
}
}
//Second Constructor function
function Bar() {
var f = new Foo(),
_this = this;
f.foo1().then(function() {
f.foo2().then(function() {
_this.bar1();
})
})
this.bar1 = function() {
alert("Bar 1 hs bee called");
_this.bar2();
}
this.bar2 = function() {
alert("Bar 2 hs bee called");
}
}
exports.module = {
Bar
}
I have exported the second function as a module, and used that in another file in this way :
//Imported Module
const myModule = require("./algorithm");
//Initiating the Bar() constructor
var x = new myModule.Bar();
This is how it works, but to make it more clear, all the work is done by the Bar() constructor, which hits the Foo() constructor for getting the data.
I hit the Bar() constructor when a button is clicked, but at the same time, when all these functions starts working, I want to terminate it any time, using another button on the same page. Let's say one button will initiate the functions and the other will stop the initiated functions, and this is my problem I can't go through.
I came up with a solution, as #Jared Smith mentioned in the comments, the only thing I have done is to add a Flag which was, TERMINATE_FUNCTION = false. Whenever the stop button is clicked, the TERMINATE_FUNCTION is set to true and on each functions in Foo() constructor it's been checked whether the TERMINATE_FUNCTION === true or not, both in the beginning and return time of the functions, and there it stop the function :
The code is :
//Boolean variable
TERMINATE_FUNCTION = false;
//Listen to event occured
event.on("stopScrapping", function(b) {
TERMINATE_FUNCTION = b;
});
//First Constructor function
function Foo() {
if (TERMINATE_FUNCTION) return;
this.foo1 = async function() {
alert("Foo 1 hs bee called");
if (!TERMINATE_FUNCTION) {
return true;
} else {
return "SCRAPPER_STOPPED";
}
}
this.foo2 = async function() {
if (TERMINATE_FUNCTION) return;
alert("Foo 2 hs bee called");
if (!TERMINATE_FUNCTION) {
return true;
} else {
return "SCRAPPER_STOPPED";
}
}
}
So far it seems goal is to control one NodeJS-based processing(running infinite loop) from completely different process/request(initiating by clicking button in browser).
There are different ways to implement inter-process communication(that is how it's named). One of them is node-ipc
Completely different approach could be moving this continuous operation to some queue manager. This way you might get additional abilities like failproof execution(so you can continue process exactly from point where it broke) or transparent parallelization.

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.

Delete instance of a class?

I have a class that was created like this:
function T() {
this.run = function() {
if (typeof this.i === 'undefined')
this.i = 0;
if (this.i > 10) {
// Destroy this instance
}
else {
var t = this;
this.i++;
setTimeout( function() {
t.run();
}, 1000);
}
}
}
Then I initialize it like var x = new T();
I'm not sure how to destroy this instance from within itself once if reaches 10 iterations.
Also, I'm not sure how to destroy it externally either, in case I want to stop it before it reaches 10.
To delete an instance, in JavaScript, you remove all references pointing to it, so that the garbage collector can reclaim it.
This means you must know the variables holding those references.
If you just assigned it to the variable x, you may do
x = null;
or
x = undefined;
or
delete window.x;
but the last one, as precised by Ian, can only work if you defined x as an explicit property of window.
Class not same function are different. Not work a delete. Class is system modification.
class SAFunc {
method1(){
console.log("1");
}
method2(){
console.log("2");
}
}
let func = new SAFunc();
func['method2']()
Try:
delete window['func'] -- not work
delete eval['func'] -- not work
delete window['SAFunc'] -- not work
...
...
Function - command work delete
method1 = function(){
console.log("func1");
}
function method2() {
console.log("func2");
}
var SAFunc = { method3: function() { console.log("func3"); } }
Make ur test... Try:
delete window['method1']
delete window['method2']
delete SAFunc['method3']
Good fun! i love programming
Enjoin us ;)

Function in JavaScript that can be called only once

I need to create a function which can be executed only once, in each time after the first it won't be executed. I know from C++ and Java about static variables that can do the work but I would like to know if there is a more elegant way to do this?
If by "won't be executed" you mean "will do nothing when called more than once", you can create a closure:
var something = (function() {
var executed = false;
return function() {
if (!executed) {
executed = true;
// do something
}
};
})();
something(); // "do something" happens
something(); // nothing happens
In answer to a comment by #Vladloffe (now deleted): With a global variable, other code could reset the value of the "executed" flag (whatever name you pick for it). With a closure, other code has no way to do that, either accidentally or deliberately.
As other answers here point out, several libraries (such as Underscore and Ramda) have a little utility function (typically named once()[*]) that accepts a function as an argument and returns another function that calls the supplied function exactly once, regardless of how many times the returned function is called. The returned function also caches the value first returned by the supplied function and returns that on subsequent calls.
However, if you aren't using such a third-party library, but still want a utility function (rather than the nonce solution I offered above), it's easy enough to implement. The nicest version I've seen is this one posted by David Walsh:
function once(fn, context) {
var result;
return function() {
if (fn) {
result = fn.apply(context || this, arguments);
fn = null;
}
return result;
};
}
I would be inclined to change fn = null; to fn = context = null;. There's no reason for the closure to maintain a reference to context once fn has been called.
Usage:
function something() { /* do something */ }
var one_something = once(something);
one_something(); // "do something" happens
one_something(); // nothing happens
[*] Be aware, though, that other libraries, such as this Drupal extension to jQuery, may have a function named once() that does something quite different.
Replace it with a reusable NOOP (no operation) function.
// this function does nothing
function noop() {};
function foo() {
foo = noop; // swap the functions
// do your thing
}
function bar() {
bar = noop; // swap the functions
// do your thing
}
Point to an empty function once it has been called:
function myFunc(){
myFunc = function(){}; // kill it as soon as it was called
console.log('call once and never again!'); // your stuff here
};
<button onClick=myFunc()>Call myFunc()</button>
Or, like so:
var myFunc = function func(){
if( myFunc.fired ) return;
myFunc.fired = true;
console.log('called once and never again!'); // your stuff here
};
// even if referenced & "renamed"
((refToMyfunc)=>{
setInterval(refToMyfunc, 1000);
})(myFunc)
UnderscoreJs has a function that does that, underscorejs.org/#once
// Returns a function that will be executed at most one time, no matter how
// often you call it. Useful for lazy initialization.
_.once = function(func) {
var ran = false, memo;
return function() {
if (ran) return memo;
ran = true;
memo = func.apply(this, arguments);
func = null;
return memo;
};
};
Talking about static variables, this is a little bit like closure variant:
var once = function() {
if(once.done) return;
console.log('Doing this once!');
once.done = true;
};
once(); // Logs "Doing this once!"
once(); // Logs nothing
You could then reset a function if you wish:
once.done = false;
once(); // Logs "Doing this once!" again
You could simply have the function "remove itself"
​function Once(){
console.log("run");
Once = undefined;
}
Once(); // run
Once(); // Uncaught TypeError: undefined is not a function
But this may not be the best answer if you don't want to be swallowing errors.
You could also do this:
function Once(){
console.log("run");
Once = function(){};
}
Once(); // run
Once(); // nothing happens
I need it to work like smart pointer, if there no elements from type A it can be executed, if there is one or more A elements the function can't be executed.
function Conditional(){
if (!<no elements from type A>) return;
// do stuff
}
var quit = false;
function something() {
if(quit) {
return;
}
quit = true;
... other code....
}
simple decorator that easy to write when you need
function one(func) {
return function () {
func && func.apply(this, arguments);
func = null;
}
}
using:
var initializer= one( _ =>{
console.log('initializing')
})
initializer() // 'initializing'
initializer() // nop
initializer() // nop
try this
var fun = (function() {
var called = false;
return function() {
if (!called) {
console.log("I called");
called = true;
}
}
})()
From some dude named Crockford... :)
function once(func) {
return function () {
var f = func;
func = null;
return f.apply(
this,
arguments
);
};
}
Reusable invalidate function which works with setInterval:
var myFunc = function (){
if (invalidate(arguments)) return;
console.log('called once and never again!'); // your stuff here
};
const invalidate = function(a) {
var fired = a.callee.fired;
a.callee.fired = true;
return fired;
}
setInterval(myFunc, 1000);
Try it on JSBin: https://jsbin.com/vicipar/edit?js,console
Variation of answer from Bunyk
Here is an example JSFiddle - http://jsfiddle.net/6yL6t/
And the code:
function hashCode(str) {
var hash = 0, i, chr, len;
if (str.length == 0) return hash;
for (i = 0, len = str.length; i < len; i++) {
chr = str.charCodeAt(i);
hash = ((hash << 5) - hash) + chr;
hash |= 0; // Convert to 32bit integer
}
return hash;
}
var onceHashes = {};
function once(func) {
var unique = hashCode(func.toString().match(/function[^{]+\{([\s\S]*)\}$/)[1]);
if (!onceHashes[unique]) {
onceHashes[unique] = true;
func();
}
}
You could do:
for (var i=0; i<10; i++) {
once(function() {
alert(i);
});
}
And it will run only once :)
Initial setup:
var once = function( once_fn ) {
var ret, is_called;
// return new function which is our control function
// to make sure once_fn is only called once:
return function(arg1, arg2, arg3) {
if ( is_called ) return ret;
is_called = true;
// return the result from once_fn and store to so we can return it multiply times:
// you might wanna look at Function.prototype.apply:
ret = once_fn(arg1, arg2, arg3);
return ret;
};
}
If your using Node.js or writing JavaScript with browserify, consider the "once" npm module:
var once = require('once')
function load (file, cb) {
cb = once(cb)
loader.load('file')
loader.once('load', cb)
loader.once('error', cb)
}
If you want to be able to reuse the function in the future then this works well based on ed Hopp's code above (I realize that the original question didn't call for this extra feature!):
var something = (function() {
var executed = false;
return function(value) {
// if an argument is not present then
if(arguments.length == 0) {
if (!executed) {
executed = true;
//Do stuff here only once unless reset
console.log("Hello World!");
}
else return;
} else {
// otherwise allow the function to fire again
executed = value;
return;
}
}
})();
something();//Hello World!
something();
something();
console.log("Reset"); //Reset
something(false);
something();//Hello World!
something();
something();
The output look like:
Hello World!
Reset
Hello World!
A simple example for turning on light only once.
function turnOnLightOnce() {
let lightOn = false;
return function () {
if (!lightOn) {
console.log("Light is not on...Turning it on for first and last time");
lightOn = true;
}
};
}
const lightOn = turnOnLightOnce();
lightOn() // Light is not on...Turning it on for first and last time
lightOn()
lightOn()
lightOn()
lightOn()
https://codesandbox.io/s/javascript-forked-ojo0i?file=/index.js
This happens due to closure in JavaScript.
function once (fn1) {
var ran = false
var memo = null
var fn = function(...args) {
if(ran) {return memo}
ran = true
memo = fn1.apply(null, args)
return memo
}
return fn
}
I'm using typescript with node and it was #I Hate Lazy's answer that inspired me. I just assigned my function to a noop function.
let printName = (name: string) => {
console.log(name)
printName = () => {}
}
printName('Sophia') // Sophia
printName('Nico') // Nothing Happens
https://jsbin.com/yuzicek/edit?js,console
FOR EVENT HANDLER
If the function is a callback for an event listener, there is already a built-in option in the addEventListner method for just executing the callback once.
It can accept 3 parameters
Type
callback
options
options is an object that has a property called once
ex:
const button = document.getElementById('button');
const callbackFunc = () => {
alert('run')
}
button.addEventListener('click', callbackFunc, { once: true })
<button id="button">Click Once</button>
Trying to use underscore "once" function:
var initialize = _.once(createApplication);
initialize();
initialize();
// Application is only created once.
http://underscorejs.org/#once
var init = function() {
console.log("logges only once");
init = false;
};
if(init) { init(); }
/* next time executing init() will cause error because now init is
-equal to false, thus typing init will return false; */
if (!window.doesThisOnce){
function myFunction() {
// do something
window.doesThisOnce = true;
};
};
If you're using Ramda, you can use the function "once".
A quote from the documentation:
once Function
(a… → b) → (a… → b)
PARAMETERS
Added in v0.1.0
Accepts a function fn and returns a function that guards invocation of fn such that fn can only ever be called once, no matter how many times the returned function is invoked. The first value calculated is returned in subsequent invocations.
var addOneOnce = R.once(x => x + 1);
addOneOnce(10); //=> 11
addOneOnce(addOneOnce(50)); //=> 11
keep it as simple as possible
function sree(){
console.log('hey');
window.sree = _=>{};
}
You can see the result
JQuery allows to call the function only once using the method one():
let func = function() {
console.log('Calling just once!');
}
let elem = $('#example');
elem.one('click', func);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<p>Function that can be called only once</p>
<button id="example" >JQuery one()</button>
</div>
Implementation using JQuery method on():
let func = function(e) {
console.log('Calling just once!');
$(e.target).off(e.type, func)
}
let elem = $('#example');
elem.on('click', func);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<p>Function that can be called only once</p>
<button id="example" >JQuery on()</button>
</div>
Implementation using native JS:
let func = function(e) {
console.log('Calling just once!');
e.target.removeEventListener(e.type, func);
}
let elem = document.getElementById('example');
elem.addEventListener('click', func);
<div>
<p>Functions that can be called only once</p>
<button id="example" >ECMAScript addEventListener</button>
</div>
Tossing my hat in the ring for fun, added advantage of memoizing
const callOnce = (fn, i=0, memo) => () => i++ ? memo : (memo = fn());
// usage
const myExpensiveFunction = () => { return console.log('joe'),5; }
const memoed = callOnce(myExpensiveFunction);
memoed(); //logs "joe", returns 5
memoed(); // returns 5
memoed(); // returns 5
...
You can use IIFE. IIFE means Immediately Invoked Function Expression and the result is to call a function only once by the time is created.
Your code will be like this:
(function () {
//The code you want to execute only one time etc...
console.log("Hello world");
})()
Additionally, this way the data in the function remains encapsulated.
Of course and you can return values from the function and stored them into a new variable, by doing:
const/let value = (function () {
//The code you want to execute only one time etc...
const x = 10;
return x;
})()
function x()
{
let a=0;
return function check()
{
if(!a++)
{
console.log("This Function will execute Once.")
return;
}
console.log("You Can't Execute it For the Second Time.")
return;
}
}
z=x()
z() //Op - This Function will execute once
z() //OP - You can't Execute it for the second time.
I find it useful to just have a simple function that just returns true once, so you can keep the side effects higher up.
let once = () => !! (once = () => false);
once() // true
once() // false
Use like this:
if (once()) {
sideEffect()
}
This exploits the fact that you can coerce an assignment expression to return true while changing the same function into a function that returns false.
If you must have it execute a function, it can be adapted using a ternary:
let once = (x) => !! (once = () => false) ? x() : false;
Now it accepts a single function as an argument. Fun fact, the second false is never reached.
// This is how function in JavaScript can be called only once
let started = false;
if (!started) {
start() { // "do something" }
}
started = true;
}

Categories