Is there an easier way to check if a javascript function has already been called and is active besides what I have below, or is what I have below already optimized...
var isDefined = function(func) {
if(func !== undefined)
{
return true;
}
else
{
return false;
}
}
JavaScript does nothing to retain memory of a function having already been called. You can put a Boolean var flag outside of it, set it to true inside, and ensure its scope doesn't leak by putting it inside an IIFE, which may give you what you want.
If what you're doing is related to click/event listening, you may want to use something like JQuery's $.once(), which adds an event listener that removes itself after occurring once.
var isDefined = function(func) {
return (func !== undefined);
}
Related
So I have a div which has an EventListener on it which works fine. But I want the EventListener to only be triggered at certain points, which is why I added an if statement to it.
I was under the impression that you can change global variables from functions the way my code is below yet this doesn't seem to work at all. I have tried changing the variable within the function by way of window.clickDisable = false; but that does not work either. The relevant parts of the code are below, does anybody know why this is not working? Thanks.
var clickDisable = true;
if (clickDisable == false) {
document.getElementById("fight")
var fightMenu = fight.addEventListener("click", fightMenuFunction)
}
function fightMenuFunction () {
}
setTimeout(introAnimation, 7000)
function introAnimation() {
clickDisable = false;
}
There are a handful of problems with your code:
I think the best approach is to put your if statement within the body of the function. You want the body of your function to run only if the timer has elapsed, rather than the event to be bound only if the timer has elapsed.
Also, your document.getElementById was not being used. You were instead benefiting from the fact that element ids are automatically interpreted as global variables, which you can do, as I have done below, but is probably not a best practice.
var clickDisable = true;
function fightMenuFunction () {
if(!clickDisable){
console.log('This is the function running.')
}
}
fight.addEventListener("click", fightMenuFunction)
window.setTimeout(introAnimation, 7000)
function introAnimation() {
clickDisable = false;
}
<button id="fight">Fight</button>
I have a simple javascript error logging mechanism in place and it looks somewhhat like this:
window.onerror = function (ErrorMsg, Url, LineNumber, Col, Error) {
// ajax these to the server, including Error.stack}
The problem is that I'd also like to get the value of the local variables and function parameters when the error occurred. Is this even possible?
I'm thinking about modifying the Function prototype so that each time a function runs, its arguments are stored in a global array of strings and then the error handler would just add this array to the ajax call. Can JavaScript do this?
#1 Can local scope be recovered in onerror() without black magic?
Without this being bound in the scope of window.onerror() or the surrounding variables being directly accessible, it's impossible to regain access to the variables you had set.
What you're mostly wanting access to is this.arguments or arguments or the equivalent, but that's destroyed. Any hope of obtaining a key-value associative array or hash-like object would involve meta-programming ( i.e. reading the function definition to obtain the variable names, and obtaining an exception report to attempt to salvage data ).
See this answer for more on something similar:
Getting All Variables In Scope
But this "lacking functionality" is a good thing:
If you could gain access to what you're asking for, that would likely be a fault in the Javascript engine. Why? Because the variable states and contents themselves are what caused the exception/error, assuming bad code wasn't the issue to begin with.
In other words, if you could get access to a faulty variable, that might be a door into an infinite loop:
Failure due to variable contents.
Error handler triggered.
Trace contents of variable.
Failure due to variable contents.
Error handler triggered.
Trace contents of variable.
Etc.
#2 Can Javascript store all arguments of every function call by voodoo?
Yes. It can. This is probably a really bad idea ( see #1 ) but it is possible. Here is a pointer on where to start:
Is there a way to wrap all JavaScript methods with a function?
From there, what you're wanting to do is push this.arguments or equivalent to a stack of function calls. But again, this is approaching insanity for many reasons. Not the least of which is the need to duplicate all the values, lest you reference mutated variables, or be unable to access the data at all... and like I said above, the problem of bad data in general. But still, it is possible.
Is this even possible?
No. A stack trace is proof that the stack has unwound, all stack frames and all the local variables they contained are gone. As for getting the name of a variable, that is not even possible at run time.
To start off i accept #Tomalak completely.
I was also put in your situation where i needed to debug a remote running app in case of crash.
As a work around I have forked my code for you in a fiddler. Please modify according to your need.
Caveat: You have to wrap the function body with try{..}catch(e){..} as illustrated in the fiddler code.
Please read the inline comments for understanding.
window.onerror = function (errorMsg, url, lineNumber, column, errorObj) {
console.log(errorObj);
}
window.addEventListener("reportOnError", function(e){
console.log(e.detail);
/*Send to the server or any listeners for analysis.*/
//Http.send(e.detail);
});
function ExceptionReport(ex, args, scope) {
var self = {};
self.message = ex.message;
self.stack = ex.stack;
self.name = ex.name;
self.whoCalled = args.callee.caller.name == "" ? "Window": args.callee.caller.name;
self.errorInFunction = args.callee.name;
self.instanceOf = scope.constructor;
self.KeyPairValues = getParamNames(arguments.callee.caller.toString(), Array.prototype.slice.call(args)); //Contains the parameters value set during runtime
window.dispatchEvent(new CustomEvent('reportOnError', {'detail':self}));
}
//Utilties
function getParamNames(fnBody, values) {
var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg,
ARGUMENT_NAMES = /([^\s,]+)/g,
result = fnBody.slice(fnBody.indexOf('(')+1, fnBody.indexOf(')')).match(ARGUMENT_NAMES),
obj={};
fnBody.replace(STRIP_COMMENTS, '');
if(result !== null){
for(var i=0; i < result.length; i++){
obj[result[i]] = values.length !==0 ? values[i] : null;
}
}else{
obj = null;
}
return obj;
}
/*
This is a testing/sample function that throws the error
*/
function testing(a,b,c){
try{
dummy(1,2) ; //This line throws the error as reference error.
}catch(e){
ExceptionReport(e, arguments, this);
}
}
//Class Emulation: For instanceof illustration.
function testingClass(){
this.testing = testing;
}
//Named self executing function: This calls the function
var myvar = (function myvar(){
testing(1,2,3);
})();
//Illustrating instanceof in exception
var myVar2 = new testingClass();
myVar2.testing(1,2,3);
//Calling from global scope this is Window
testing(1,2,3);
//Without variables
testing();
I have used examples to illustrate the behavior of functions called in different circumstances.
Below signifies the varialble used for
self.KeyPairValues : Used to store the function parameter set/passed during runtime
self.errorInFunction : This stores the name of the function error was caused in.
self.whoCalled : This stores the function name that invoked the defective function
self.instanceOf : This stores the name of the instance is called creating a new instance.
Other variables are same as in Error object
The others answers here are spot on, but I might be able to offer a suggestion for a slightly different way to accomplish this. Instead of trying to track all scope in your program, why not add a tagging function that tracks the scope of one function's parameters without affecting the runtime of the function. For for example:
var globalRecord = {};
function record(name, fn) {
return function () {
var args = [].slice.call(arguments);
var record = globalRecord[name] = {
args: args,
arg: {}
};
args.unshift(function (name, value) {
return record[name] = value;
});
fn.apply(args, arguments);
}
}
// Then, you track variables like this
var func = record("func", function (record, a, b, c) {
record("a", a); // named parameters are accessible now
record("b", b); // if some error occurs in the function body
return a + b + c;
});
// Calling func still behaves as before.
func(1, 2, 3);
// Errors handled like this:
window.onerror = function () {
globalRecord.func.args; // ==> last set of arguments past to function
globalRecord.func.arg.a; // specific arguments recorded with names
};
You could even use this method to track scope without using a function by anonymously calling the recorded function.
record("test", function (record) {
var a = record("a", /* whatever */);
var b = record("b", /* ... */ );
// do scope specific stuff that might fail
})();
Of course, this isn't a polished implementation by any stretch, but with a little work, I think you might be able to get the behavior you're looking for without any seriously black magic. By selectively adding and removing record calls as the need presents itself, you can have precise control over what is logged without any intrusive hacks.
You can find your answer in this link.
Before taking bundles from the server, you must modify them. For example, to solve your problem, you can do changes in the mentioned link as follows. In the BuildBundleContent Class make this change:
contents.Insert(blockContentIndex,
string.Format("if(customErrorLogging)customErrorLogging({0}, this){1}",
errVariable, hasContent ? ";" : ""));
If in the modules you have to use something like:
var self = this;
You can use:
contents.Insert(blockContentIndex,
string.Format("if(customErrorLogging)customErrorLogging({0}, self ? self : this){1}",
errVariable, hasContent ? ";" : ""));
And in added js file:
"use strict";
var customErrorLogging = function (ex, module) {
console.log(module);
//do something...
};
I hope help you.
So I want to call a function
myfunction();
I want to be able to have my code call it once and be fine but if my code calls it a second time, I want to check to see if certain conditions are true and if they are, I want the function to not run. If these conditions aren't true, then I want the function to run as usual. I just want to know if something specific is true only for a second call to the function and not allow my function to run again until those conditions aren't true anymore.
if(condition) {
//don't run function code for as long as this is true.
}
else{
//business as usual, run the code
}
I want to do this always on the second call to the function. So first function call, no checking. On a second call, check. On a 3rd call no checking, on the 4th call check etc. Basically, every other call to the function, check to see if certain conditions are true
and if they are, don't run the function code. I would very much appreciate your response.
This is easy enough. Since what you're looking for is basically a function that modifies its behavior according to some internal state, it's an ideal application for objects:
var o = {
calls: 0,
fn: function(){
if(++this.calls%2){
console.log('odd call');
} else {
console.log('even call');
}
}
}
If you absolutely must have a function only (no object), you can use an immediately-invoked function expression (IIFE) to return a function:
var fn = (function(){
var calls = 0;
return function(){
if(++calls%2){
console.log('odd call');
} else {
console.log('even call');
}
}
})();
This has the advantage of encapsulating the calls variable: that can't be accessed or tampered without outside of the function.
As a cautionary note, what this achieves is called a "side effect": that is, the behavior of the function can no longer be predicted without understanding the details of the function. I'm not going to be dogmatic and say side effects are always bad, but you do have to be careful with them: make sure they make sense, and that your documentation is clear about what's happening.
you'd need an index variable outside of the function scope.
something like this:
var index = 0;
function myFunction() {
// TRUE on every second call
if (++index % 2 === 0) {
if (condition) {
// ....
} else {
// ...
}
}
// ....
}
You could use a closure: instead of
function f(x, y, z) {
... normal processing ...
}
create a closure that every other call will do the check
var f = (function(){
var do_check = true;
return function(x, y, z){
do_check = !do_check;
if (do_check && ... check ...) {
... special handling ...
} else {
... normal processing ...
};
})();
As others said however I'd say that keeping this behavior hidden inside the function seems a bad idea. Probably a better solution is just externalize (and document) the state.
This is not an answer to your question.
For sure there will be answers that tell you how to do this, but I'd argue that "The only winning move is not to play."
Having functions that behave differently between calls make will make your software very hard to work with (maintain, test, debug, reason about).
Should there be a reason for needing the function to behave differently between calls, make it about the state of the system, not purely about the function itself.
Agree with pkyeck, but why increase a var.
var checkCall = 1;
function myfunction(){
if(checkCall){
alert('true: so no code will run');
checkCall = 0;
} else {
alert('run the code');
checkCall = 1;
}
}
I am working on small part of calculation code. I need to identify whenever recursive occur in javascript/jQuery and i need to terminate that recursive.
Is there any api to support this in javascript/jQuery?
You could implement your own recursive protection. There is nothing built into jQuery that would natively support preventing recursion.
function myFunc(arg) {
// if this function already executing and this is recursive call
// then just return (don't allow recursive call)
if (myFunc.in) {
return;
}
// set flag that we're in this function
myFunc.in = true;
// put your function's code here
// clear flag that we're in this function
myFunc.in = false;
}
myFunc.in = false;
You could also turn the boolean into a counter and allow recursion only up to a certain number of levels.
FYI, because JS is single threaded, this should only be an issue that might need protection if your function takes some sort of callback from code that isn't yours. If it's all your own code, then you should just make sure your own code won't cause this sort of problem.
Here's a little more foolproof version that protects the counter in a closure so it can't be manipulated outside the function:
var myFunc = (function() {
var inCntr = 0;
return function(args) {
// protect against recursion
if (inCntr !== 0) {
return;
}
++inCntr;
try {
// put your function's code here
} finally {
--inCntr;
}
}
})();
Note: this uses a try/finally block so even if your code or any code you call throws an exception the counter is still cleared (so it never gets stuck).
Another dodgy trick. If you use something like .bind(this) for recursion or if you use arrow function, it won't work.
boom();
function boom () {
if(arguments.callee === arguments.callee.caller) {
console.log('no recursion will happen');
return;
}
boom();
}
Simple solution could be a flag in a parameter
boom2();
function boom2 (calledRecursively) {
if(calledRecursively) {
console.log('no recursion will happen');
return;
}
boom2(true);
}
This is related to this
Anyway what I need is actually something slightly different I need some way of doing this:
function run(arg) {
this.ran = this.ran || false;
if (!this.ran) init;
/* code */
this.ran = true;
}
This works fine, I just want to make sure that this code works even when this in case it was called with call() or apply()
Check this out for what I'm talking about, All of the calls after the first one should all be true, no matter the context
to get full use of closures, i suggest you wrap your main function in another function that initiates the "ran" flag :
function initRun(){
var ran = ran || false;
return function(arguments){
if(ran)
{
console.log("can't run any more!");
return;
}
ran = true;
console.log("i'm running!");
/* your logic here */
}
}
var run = initRun();
then you can test it by calling your function in whatever way you want :
run();
run.call();
run.apply();
it successfully runs only once, no matter the calling method used.
The mini-downside is that you need an extra function that wraps your initial "run" function, but i think it's more reliable and elegant than to use a global flag that keeps track of your function calls
you can replace "this" by "arguments.callee". arguments.callee should always give you the object representing your current function thus isolating you from changing "this". (However I did not test^^)
When you define a free-standing function, "this" refers to the global window object. When that is the case, you might as well just use the global variable explicitly to avoid any chance of "this" from being usurped from .apply() or .call()... provided that is the desired behavior.
function run(arg) {
window.ran = window.ran || false;
if (!window.ran) init();
/* code */
window.ran = true;
}
As a side note, if you define a function as a property of an object, "this" refers to the owning object. Note that "this" is a reference to a function's owner, and the owner depends on the context.
EDIT: also, as a followup to #Anurag's suggestion, is this unsuitable?
var run = (function createRun() {
var ran = false;
return function(arg) {
if (!ran) init;
// code
ran = true;
};
})();
run(arg);