I'm trying to create javascript closure that will tell me if the function has already been run:
This is what I have so far:
function do()
{
var isInitialized = function()
{
var init = false;
if (init == false)
{
init = true;
return false;
}
return init;
}
if (!isInitialized())
{
// do stuff
}
}
My function isInitialized always evaluates to true. I'm like 90% sure I'm not setting the internal variable correctly. How do I fix my code?
First of all, you can't use do as your function name as that's a keyword.
Secondly, you can attach properties right to your function so you don't need a closure or anything like this:
function f() {
if(f.initialized)
return;
f.initialized = true;
console.log('Doing things.');
}
f();
f();
That will give you just one "Doing things." in the console.
Demo (run with your JavaScript console open): http://jsfiddle.net/ambiguous/QK27D/
Functions are objects in JavaScript so they can be assigned properties which provides a convenient mechanism for achieving what you want to do:
function doit() {
if (typeof doit.isInitialized === "undefined") {
doit.isInitialized = true;
// do stuff
}
}
Try this:
function fn(){
if (typeof fn.hasrun!='undefined'){return;}
fn.hasrun=true;
// do stuff
}
Every time you call isinitialized, it'll reset all the variables to default, so init will ALWAYS start out false. The values set afterwards are NOT carried over to the next time isInitialiazed is called.
What you want is a 'static' variable, which JS doesn't directly support, but can be simulated as per this answer: Static variables in JavaScript
Related
function check_and_kill(selector){
(function checkState(selector){
if(selector.attr('type')){
return false;
}else{
return true;
}
})(),
kill = function(){
if(this.checkState() == false){
console.log('kill all')
}
}
}
$('something').click(){
check_and_kill($(this));
}
I try to make checkState as my constructor, the the second function which is kill react depends on the value returned by the constructor, but I can't pass the selector, it return undefined.
Following is the simulation of both cases.
Code
function Class(str){
(function(str){
document.write(str)
})(str) // Binding value
}
function Class2(str){
(function(str){
document.write(str)
})() // Not binding value
}
(function(){
var a = new Class("Hello World. ");
var b = new Class2(" Hello World ")
})()
You don't store the value from the constructor...
checkState = (function checkState(selector){
if(selector.attr('type')){
return false;
}else{
return true;
}
})(),
or call the kill function... also you should take a long hard look at the syntax for your call to .click.... also .click doesn't have reference to a "this"
Here's a working example in the spirit of what you're trying to do:
https://jsfiddle.net/n2zk1wym/
Here's a working example that does what you're trying to do, without all the bells and whistles. Your attempt to use the finer aspects of the javascript language are commendable, but totally unnecessary for this particular problem:
https://jsfiddle.net/2mL9jh2a/
I only want my JavaScript to run once, but I cannot control how many times the javascript file is executed. Basically I'm writing a tiny JS snippet into a CMS, and the CMS is actually calling it 5-10 times. So solutions like this:
function never_called_again(args) {
// do some stuff
never_called_again = function (new_args) {
// do nothing
}
}
never_called_again();
Don't seem to work because as soon as my snippet is run again from the top the function is re-declared, and 'do some stuff' is re-evaluated. Perhaps I'm just not doing it properly, I'm not great with JS. I'm considering using something like try-catch on a global variable, something like
if (code_happened == undefined) {
\\ run code
code_happened = true;
}
EDIT: There is a consistent state e.g. if I set a variable I can see when my snippet is run again. But having to declare it before I access it, I don't know how to say 'does this variable exist yet'
Try this:
var doneTheStuff;
function whatever() {
if (!doneTheStuff) {
doneTheStuff = true;
// do the stuff
}
}
Redundant variable declarations don't affect the value of the variable. Once one of the functions has set the variable to true, the others won't do anything.
if (typeof code_happened === 'undefined') {
window.code_happened = true;
// Your code here.
}
The typeof check gets you around the fact that the global hasn't been declared. You could also just do if (!window.code_happened) since property access isn't banned for undefined properties.
Use a closure, and set a flag. If the flag is true, just return:
if ( ! window.never_called_again ) {
window.never_called_again = (function () {
var ran = false;
return function (args) {
if ( ran ) return;
ran = true;
// Do stuff
};
}());
}
Here's the fiddle: http://jsfiddle.net/U2NCs/
With jQuery, the function .one() may be useful : http://api.jquery.com/one/
W3School exemple here : http://www.w3schools.com/jquery/event_one.asp
In this way, the code is executed only once.
if(typeof onceRun == "undefined") window.onceRun=(
()=>{
//your codes...
console.log("runing...")
return true
}).call()
I am trying to write a logger object which logs messages to screen. here is my code.
http://github.com/huseyinyilmaz/javascript-logger
in every function that needs to log something, I am writing loggerstart and loggerEnd functions at start and end of my functions. But I want to run thos codes automaticalls for every function. is there a way to modify Function prototype so every function call can run automatically.
(I am not using any javascript framework.)
EDIT: Rewritten the function to make it more modular
Well, this is a creepy way to do it, but I use this way sometimes when I need overriding some functions. It works well, allows any kind of customization and easy to understand (still creepy).
However, you will need to have all your functions stored in some kind of global object. See the example for details.
function dynamic_call_params(func, fp) {
return func(fp[0],fp[1],fp[2],fp[3],fp[4],fp[5],fp[6],fp[7],fp[8],fp[9],fp[10],fp[11],fp[12],fp[13],fp[14],fp[15],fp[16],fp[17],fp[18],fp[19]);
}
function attachWrapperToFunc(object, funcName, wrapperFunction) {
object["_original_function_"+funcName] = object[funcName];
object[funcName] = function() {
return wrapperFunction(object, object["_original_function_"+funcName], funcName, arguments);
}
}
function attachWrapperToObject(object, wrapperFunction) {
for (varname in object) {
if (typeof(object[varname]) == "function") {
attachWrapperToFunc(object, varname, wrapperFunction);
}
}
}
And some usage example:
var myProgram = new Object();
myProgram.function_one = function(a,b,c,d) {
alert(a+b+c+d);
}
myProgram.function_two = function(a,b) {
alert(a*b);
}
myProgram.function_three = function(a) {
alert(a);
}
function loggerWrapperFunction(functionObject, origFunction, origFunctionName, origParams) {
alert("start: "+origFunctionName);
var result = dynamic_call_params(origFunction, origParams);
alert("end: "+origFunctionName);
return result;
}
attachWrapperToObject(myProgram,loggerWrapperFunction);
myProgram.function_one(1,2,3,4);
myProgram.function_two(2,3);
myProgram.function_three(5);
Output will be:
start,10,end,start,6,end,start,5,end
So generally it allows you to wrap each function in some object automatically with a custom written wrapper function.
You could call every function with a wrapper function.
function wrapper(callback) {
loggerstart();
callback();
loggerend();
}
And call it with wrapper(yourfunction);
I would just like to ask whether I would be able to unit test the code inside ExternalFunction within the document.ready? I have tried many things for a while now and still couldn't work out how, and am at my wits end.
$(document).ready(function () {
var originalExternalFunction = ExternalFunction;
ExternalFunction = function(context, param) {
// trying to unit test the stuff in here!
}
}
I'm unit testing using JsTestDriver. Test declaration is something like TestThisTest.prototype.test_this - function() {};
Thanks in advance.
Since, in your example, ExternalFunction is not declared within the scope of the function, it is global (or at least, in whatever scope it may have been defined in outside ready). You can therefore test it by calling it as a global.
The trouble is, in order to assign the function to ExternalFunction, you have to run ready (which you could run manually, if you need). This means that if you put any other functionality in ready, then no, it is not unit testable. If your example code is an accurate reflection of reality, then I suppose it is kinda testable.
The point of a construct like this, is to hide the inner function. If you don't wish to hide it, then Anon.'s suggestion of defining newExternalFunction in a more accessible scope is what you need.
If your function needs to be a closure using variables from within ready, you could define newExternalFunction thus:
var newExternalFunction;
$(document).ready(function () {
var originalExternalFunction = ExternalFunction;
newExternalFunction = function(context, param) {
// trying to unit test the stuff in here!
}
ExternalFunction = newExternalFunction;
}
You would still need to ensure that ready has run, prior to unit testing, but you wouldn't have to rely on ExternalFunction not being reset to originalExternalFunction.
You could do something like:
function newExternalFunction(context, param) {
//etc.
}
$(document).ready(function () {
var originalExternalFunction = ExternalFunction;
ExternalFunction = newExternalFunction;
}
Then it's relatively straightforward to run your unit tests on newExternalFunction.
Theoretically, you could do something like:
ExternalFunction = function() { }
ExecuteDocumentReady(); // implement a mock on $(document).ready(fn) to store the function, and then execute it here
ExternalFunction(fakeContext, fakeParam);
assert(fakeContext.foo == 12); // or whatever you need it to do
That being said, I'm not sure exactly how to do that in javascript.
You could use a closure to generate your callback function:
// create function to make your "extension" function
function createHookFunction(callback) {
// return a function
return function(context, param) {
var ret;
// // trying to unit test the stuff in here!
if (typeof callback == 'function') {
// if you want to trap the return value from callback,
// ret = callback.apply(...);
callback.apply(this, arguments);
}
return ret;
};
}
// your hook now becomes:
$(document).ready(function() {
ExternalFunction = createHookFunction(ExternalFunction);
});
// and your unit test becomes:
var funcToTest = createHookFunction();
funcToTest(testContext, testParam);
// And, you could even test that the callback itself gets called
function someTest() {
var testContext = {}, testParam='test';
var callbackCalled = false;
var funcToTest = createHookFunction(function(context, param) {
callbackCalled = (context === testContext) && (param === testParam);
});
return (funcToTest(testContext, testParam) == 'Expected Return') && callbackCalled;
}
I have a function, a(), that I want to override, but also have the original a() be performed in an order depending on the context. For example, sometimes when I'm generating a page I'll want to override like this:
function a() {
new_code();
original_a();
}
and sometimes like this:
function a() {
original_a();
other_new_code();
}
How do I get that original_a() from within the over-riding a()? Is it even possible?
Please don't suggest alternatives to over-riding in this way, I know of many. I'm asking about this way specifically.
You could do something like this:
var a = (function() {
var original_a = a;
if (condition) {
return function() {
new_code();
original_a();
}
} else {
return function() {
original_a();
other_new_code();
}
}
})();
Declaring original_a inside an anonymous function keeps it from cluttering the global namespace, but it's available in the inner functions.
Like Nerdmaster mentioned in the comments, be sure to include the () at the end. You want to call the outer function and store the result (one of the two inner functions) in a, not store the outer function itself in a.
The Proxy pattern might help you:
(function() {
// log all calls to setArray
var proxied = jQuery.fn.setArray;
jQuery.fn.setArray = function() {
console.log( this, arguments );
return proxied.apply( this, arguments );
};
})();
The above wraps its code in a function to hide the "proxied"-variable. It saves jQuery's setArray-method in a closure and overwrites it. The proxy then logs all calls to the method and delegates the call to the original. Using apply(this, arguments) guarantees that the caller won't be able to notice the difference between the original and the proxied method.
Thanks guys the proxy pattern really helped.....Actually I wanted to call a global function foo..
In certain pages i need do to some checks. So I did the following.
//Saving the original func
var org_foo = window.foo;
//Assigning proxy fucnc
window.foo = function(args){
//Performing checks
if(checkCondition(args)){
//Calling original funcs
org_foo(args);
}
};
Thnx this really helped me out
You can override a function using a construct like:
function override(f, g) {
return function() {
return g(f);
};
}
For example:
a = override(a, function(original_a) {
if (condition) { new_code(); original_a(); }
else { original_a(); other_new_code(); }
});
Edit: Fixed a typo.
Passing arbitrary arguments:
a = override(a, function(original_a) {
if (condition) { new_code(); original_a.apply(this, arguments) ; }
else { original_a.apply(this, arguments); other_new_code(); }
});
The answer that #Matthew Crumley provides is making use of the immediately invoked function expressions, to close the older 'a' function into the execution context of the returned function. I think this was the best answer, but personally, I would prefer passing the function 'a' as an argument to IIFE. I think it is more understandable.
var a = (function(original_a) {
if (condition) {
return function() {
new_code();
original_a();
}
} else {
return function() {
original_a();
other_new_code();
}
}
})(a);
The examples above don't correctly apply this or pass arguments correctly to the function override. Underscore _.wrap() wraps existing functions, applies this and passes arguments correctly. See: http://underscorejs.org/#wrap
In my opinion the top answers are not readable/maintainable, and the other answers do not properly bind context. Here's a readable solution using ES6 syntax to solve both these problems.
const orginial = someObject.foo;
someObject.foo = function() {
if (condition) orginial.bind(this)(...arguments);
};
I had some code written by someone else and wanted to add a line to a function which i could not find in the code. So as a workaround I wanted to override it.
None of the solutions worked for me though.
Here is what worked in my case:
if (typeof originalFunction === "undefined") {
originalFunction = targetFunction;
targetFunction = function(x, y) {
//Your code
originalFunction(a, b);
//Your Code
};
}
I've created a small helper for a similar scenario because I often needed to override functions from several libraries. This helper accepts a "namespace" (the function container), the function name, and the overriding function. It will replace the original function in the referred namespace with the new one.
The new function accepts the original function as the first argument, and the original functions arguments as the rest. It will preserve the context everytime. It supports void and non-void functions as well.
function overrideFunction(namespace, baseFuncName, func) {
var originalFn = namespace[baseFuncName];
namespace[baseFuncName] = function () {
return func.apply(this, [originalFn.bind(this)].concat(Array.prototype.slice.call(arguments, 0)));
};
}
Usage for example with Bootstrap:
overrideFunction($.fn.popover.Constructor.prototype, 'leave', function(baseFn, obj) {
// ... do stuff before base call
baseFn(obj);
// ... do stuff after base call
});
I didn't create any performance tests though. It can possibly add some unwanted overhead which can or cannot be a big deal, depending on scenarios.
So my answer ended up being a solution that allows me to use the _this variable pointing to the original object.
I create a new instance of a "Square" however I hated the way the "Square" generated it's size. I thought it should follow my specific needs. However in order to do so I needed the square to have an updated "GetSize" function with the internals of that function calling other functions already existing in the square such as this.height, this.GetVolume(). But in order to do so I needed to do this without any crazy hacks. So here is my solution.
Some other Object initializer or helper function.
this.viewer = new Autodesk.Viewing.Private.GuiViewer3D(
this.viewerContainer)
var viewer = this.viewer;
viewer.updateToolbarButtons = this.updateToolbarButtons(viewer);
Function in the other object.
updateToolbarButtons = function(viewer) {
var _viewer = viewer;
return function(width, height){
blah blah black sheep I can refer to this.anything();
}
};
Not sure if it'll work in all circumstances, but in our case, we were trying to override the describe function in Jest so that we can parse the name and skip the whole describe block if it met some criteria.
Here's what worked for us:
function describe( name, callback ) {
if ( name.includes( "skip" ) )
return this.describe.skip( name, callback );
else
return this.describe( name, callback );
}
Two things that are critical here:
We don't use an arrow function () =>.
Arrow functions change the reference to this and we need that to be the file's this.
The use of this.describe and this.describe.skip instead of just describe and describe.skip.
Again, not sure it's of value to anybody but we originally tried to get away with Matthew Crumley's excellent answer but needed to make our method a function and accept params in order to parse them in the conditional.