I have an input which when im clicking - i want to see alert with '1,2,3,4...' (each press)
<input type='button' value='press' onclick='Clicked();' />
<script>
var t
function Clicked()
{
t=func;
t();
}
function func()
{
var count=0;
return new function () // <=== new or not new ???
{
count++;
alert(count);
}
}
</script>
If im adding the 'new' in the return and click , it says : '1,1,1,1,...'
If im removing the 'new' it doesnt work...
My goal is to use this to get : '1,2,3,4...'
Can someone explain to me what happens ?
You need to use the returned function:
var t = func()
function Clicked() {
t();
}
function func() {
var count=0;
return function () {
count++;
alert(count);
}
}
Example
You have to put the count declaration out of the "func" function and into the global namespace. Like this:
var count=0;
function func() {
count++;
alert(count);
}
You're creating a new var count every time the clickevent fires.. You should place the var count = 0 outside the function as a global variable..
oh and btw, throw out the return stuff please this will work properly:
var count = 0;
function func()
{
count++;
alert(count);
}
And call this method like this: func();
You are getting 1,1,1,1 because you are redefining count every time you call func().
In your case you will need to either put the count variable in the global scope:
var t;
var count = 0;
or change the way you are doing things a little:
var t = 0;
function Clicked(){
t = func(t);
}
function func(count){
count++;
alert(count)
return count;
}
Personally I like the second one. You have less global variables, one less function declaration, and it is cleaner
var t
function Clicked()
{
t=func;
t();
}
var count=0;
function func()
{
return new function () // <=== new or not new ???
{
count++;
alert(count);
}
}
Related
Let's say I have a JS function that returns a value but has an alert command in it. I want to assign the returned value to a variable later on in the code. Is there a way to call the function but to ignore the alert command, in order to just assign the returned value to a variable later?
For example:
Let's say I havefunction f1(num) { alert ("hi); return num * 2; }
and thenfunction f2() { var x = f1(2); return x;}.
How can I ignore the alert and only save the returned
value in a variable on later functions?
Add an additional parameter to f1() to skip the alert:
function f1(num, skipAlert) {
if (skipAlert !== true) alert("hi");
return num * 2;
}
function f2() {
var x = f1(2);
return x;
}
function f2_skipAlert() {
var x = f1(2, true);
return x
}
document.querySelector('button#alert').addEventListener('click', function () {
console.log(f2());
});
document.querySelector('button#skip-alert').addEventListener('click', function () {
console.log(f2_skipAlert());
});
<button id="alert">Run with alert</button>
<button id="skip-alert">Run without alert</button>
Solution if you cannot change the f1 function
You can disable it with the following. Remember to define the disable function before the execution of the one that contains the alert function.
window.alert = function() {};
If you need to re-enable it, you can do temporarily associate it to another variable:
var oldalert = window.alert;
Then disable it as I did before and then re-enable later with window.alert = oldalert;
As esqew said, it's not a good practice to override it
Example of Use
function disableAlert(){
window.oldalert = window.alert;
window.alert = function() {};
}
function enableAlert(){
window.alert = window.oldalert;
}
And then, in your f2 function you can do like this:
function f2() {
disableAlert();
var x = f1(2);
enableAlert();
return x;
}
Solution if you can change the f1 function
Similar to esqew solution but using default parameters
function f1(num, skipAlert = false) {
if (skipAlert) alert("hi");
return num * 2;
}
function f2(skipAlert = false) {
var x = f1(2, skipAlert);
return x
}
If you want to call with alert you can use f2(true) otherwise just f2().
I am quite new to javascript and i have encounter problems about function call and the closure.
Below are the code that i tried in w3schools,
<!DOCTYPE html>
<html>
<body>
<p>Counting with a local variable.</p>
<button type="button" id="btn">Count!</button>
<p id="demo">0</p>
<script>
var add = (function (test) {
var counter = 0;
return function (test) {return counter += test;}
})();
/*function add(test){
var counter = 0;
return function (test) {return counter += test;}
}*/
function myFunction(){
document.getElementById("demo").innerHTML = add(123);
//document.getElementById("demo").innerHTML = add().call(this, 123);
}
var btn = document.getElementById("btn");
btn.addEventListener("click", myFunction);
</script>
</body>
</html>
It works fine for the current code, that every time i press the button, the number in the paragraph(id="demo") increment by 123.
But when i tried the commented code, which create a function with closure with exact same code, the paragraph value remain at 123 every onclick.
In this situation, i have a few questions to ask.
1.For the code :
var add = (function (test) {...}) ();
What is the usage of the last bracket? If we provide parameter to the last bracket, how can we use it in the declaration of the anonymous function of variable (var add)?
2.Why these two ways to define the function result in different result?
Thanks a lot, any help is appreciated.
EDIT
<!DOCTYPE html>
<html>
<body>
<p>Counting with a local variable.</p>
<button type="button" id="btn">Count!</button>
<p id="demo">0</p>
<script>
/*var add = (function (test) {
var counter = 0;
return function (test) {return counter += test;}
})();*/
function add(test){
var counter = 0;
return function (test) {return counter += test;}
}
function myFunction(){
//document.getElementById("demo").innerHTML = add(123);
document.getElementById("demo").innerHTML = add().call(this, 123);
}
var btn = document.getElementById("btn");
btn.addEventListener("click", myFunction);
</script>
</body>
</html>
It seems that the code run with no error occur, when i use the commented code for declaration of function, but just a bug that the integer of the paragraph didn't increment.
The reason you are getting 123 all the time is because every time you click on the button, you take a new inner function with a closure on counter variable with value 0; So value of counter always remains 0 and when you add 123 to 0 you get 123.
If you move closure part out of the event handler, you would get exact same result as in the first case.
Notice the line var inner = add(); //<---Notice this line. This would take the closure one time and subsequently you will keep increasing the value of counter.
Also, notice this line inside myFunction:
document.getElementById("demo").innerHTML = inner.call(this, 123);
Here we are calling the inner function that we had reference on earlier.
/*var add = (function (test) {
var counter = 0;
return function (test) {return counter += test;}
})();*/
function add(test) {
var counter = 0;
return function(test) {
return counter += test;
}
}
var inner = add(); //<---Notice this line
function myFunction() {
//document.getElementById("demo").innerHTML = add(123);
document.getElementById("demo").innerHTML = inner.call(this, 123);
}
var btn = document.getElementById("btn");
btn.addEventListener("click", myFunction);
<p>Counting with a local variable.</p>
<button type="button" id="btn">Count!</button>
<p id="demo">0</p>
() is to invoke the anonymous function you just declare, and it return another anonymous function. If you provide a parameter, it will be fed to your function (test). In this case, you don't actually need the first test parameter. It's just not used.
For your commented code, it returns a function. And the function is never invoked.
() The last bracket is to execute it.
The example u have shown is that of an IIFE.
IIFE are used to limit scope of all ur variable so that namespaces can be demarkcated.
//without params
(function(){
//...
})()
//-OR- (both are same)
(function(){
//...
}())
//with params. if u ever wondered how that $ variable was being used in jquery, this is how.
(function(jquery){
})(jquery);
//es6
(
() => { ... }
)()
closure is a programming concept in which (otherwise) scoped-out variables are allowed to persist. DO NOT use closure with big object collections !!!
var outer = function(p1){
var inner = function (p2) {
return (p1 + p2);
return inner;
}; //outer ends.
var x = outer(10);
x(20); //20 + 10;
x(30); //30 + 10;
x(40); //40 + 10;
I'm trying to call a function that's returned from a function. Here's what I mean:
myFunction.something; // (Wrong)
function myFunction() {
return {
something: function() {
...
}
};
}
When I try calling myFunction.something nothing happens. How can I call a returned function outside of its function?
JSFiddle
var index = 0;
var animID = requestAnimationFrame(myFunction.something);
function myFunction() {
return {
something: function() {
index++;
console.log(index);
if (index === 5) cancelAnimationFrame(animID);
else animID = requestAnimationFrame(myFunction.something);
}
};
}
I would first of all recommend using descriptive variable names; utils rather than myFunction, and incrementFrame rather than something, for example. I would second of all recommend reconsidering your approach to code organization and simply putting all of your helper functions directly in an object, then referencing that object:
var index = 0;
var animID = requestAnimationFrame(utils.incrementFrame);
var utils = {
incrementFrame: function() {
index++;
console.log(index);
if (index === 5) cancelAnimationFrame(animID);
else animID = requestAnimationFrame(utils.incrementFrame);
}
}
There are a few differences between these approaches, some of them frustratingly subtle. The primary reason I recommend using an object for organization rather than a function which returns an object is because you don't need to use a function for organization; you are unnecessarily complicating your code.
myfunction is not the object that you get from calling myfunction(), it's the function itself and does not have a .something method.
You could call it again (as in myfunction().something()), but a better approach would be to store a reference to the object you've already created:
function myFunction() {
var index = 0;
var o = {
something: function() {
index++;
console.log(index);
if (index < 5) requestAnimationFrame(o.something);
// btw you don't need to cancel anything once you reach 5, it's enough to continue not
}
};
return o;
}
myFunction().something();
Alternatively you might want to drop the function altogether, or use the module pattern (with an IIFE), as you seem to use it like a singleton anyway.
Try this:
myFunction().something()
myFunction() calls the myFunction function
them we use the dot notation on the returned value (which is an object) to find the something member of it
that member is a function too, so add another set of brackets () to call it
Call function after writing it
var index = 0;
function myFunction() {
return {
something: function() {
index++;
console.log(index);
if (index === 5) cancelAnimationFrame(animID);
else animID = requestAnimationFrame(myFunction().something);
}
};
}
var animID = requestAnimationFrame(myFunction().something);
I have this code which calls a function test() on body onload
<body onLoad="test();">
The Test function has 2 more functions drawLayers() ,StopAll().
function test() {
function drawLayers() {
timers = [];
timers.push(setTimeout(drawMoon,800));
timers.push(setTimeout(drawCircle1,2300));
timers.push(setTimeout(drawCircle2,2700));
timers.push(setTimeout(drawCircle3,3100));
timers.push(setTimeout(drawCircle4,3500));
timers.push(setTimeout(drawCircle5,3900));
timers.push(setTimeout(drawtext2,4300));
timers.push(setTimeout(drawtext,4700));
timers.push(setTimeout(drawtext3,5100));
timers.push(setTimeout(drawtext4,5500));
timers.push(setTimeout(drawtext5,5900));
timers.push(setTimeout(drawtext6,6300));
timers.push(setTimeout(drawtext7,6700));
timers.push(setTimeout(drawtext8,7100));
timers.push(setTimeout(drawtext9,7500));
timers.push(setTimeout(drawtext10,7900));
}
function StopAll() {
alert('fsdfsdf');
for (var i = 0; i < timers.length; i++)
window.clearTimeout(timers[i]);
}
}
What i want to do is Call the StopAL() function on click of a button, the html code looks like below
<a href="javascript:void(0);" onClick="StopAll();">
Its throwing error, "StopAll is not defined"
How do i call the StopALL() function?
The scope of those nested functions is restricted to the test function only. You cannot invoke them from the outside. If you need to do that you could externalize it from the test function.
This is a 'closure' problem. The function StopAll is within the scope of the test function, and therefore is undefined in the global scope in which you are trying to call it.
Closures are a tricky subject to grasp initially. There's a good explanation here:
How do JavaScript closures work?
(by the way StopAll should really be called stopAll because capitalised functions are generally reserved for use with the new keyword.)
test = function (){
this.drawLayers = function() {
this.timers = [];
this.timers.push(setTimeout(drawMoon,800));
}
this.StopAll = function() {
alert('fsdfsdf');
var t = timers.length
for (var i = 0; i < t; i++)
window.clearTimeout(this.timers[i]);
}
}
var testObj = new test();
testObj.StopAll()
function test() {
function drawLayers() {
timers = [];
timers.push(setTimeout(drawMoon,800));
timers.push(setTimeout(drawCircle1,2300));
timers.push(setTimeout(drawCircle2,2700));
}
var StopAll=function() {
alert('fsdfsdf');
for (var i = 0; i < timers.length; i++)
window.clearTimeout(timers[i]);
}
return StopAll;
}
var obj= new test();
//to call StopAll function
obj();
(function test($) {
function drawLayers() {
}
//expose this to outside world ,public function
$.StopAll = function() {
alert('fsdfsdf');
}
})(window);
StopAll();
You'd better not use html attributes to bind event handler, you can do the same with the following code:
window.onload = function(){
document.getElementById("myLink").onclick = function(){
StopAll();
}
}
// Your functions
This way you'll ensure your dom is loaded and ready to call event handlers.
You can move the function StopAll() outside the test function and call it as specified. If suppose you need to access that function even in the test(), you can do like this
function test() {
.....
drawLayers();
StopAll() ;
}
function StopAll() {
alert('fsdfsdf');
for (var i = 0; i < timers.length; i++)
window.clearTimeout(timers[i]);
}
Declaration of function can be given outside and called any where you want
My code looks something like:
$(document).ready(function(){
var cont = 0;
function func1(cont)
{
//Some code here
search.setSearchCompleteCallback(this, searchComplete, null);
//Some other code
}
func1(cont);
function searchComplete()
{
//Some code
cont += 1;
if (cont < length ) {
func1(cont);
} else {
// Other code
}
}
});
So what I want to do is delay the execution of func1(cont); inside of the searchComplete() function. The reason for this is that all the code does is to work with the Google search API and PageRank checks and I need to slow down the script so that I won't get banned. (Especially for the requests it makes regarding the PR check).
If I simply use setTimeout() on func1(cont); it says there is no func1() defined, if I try to get the function outside $(document).ready() it sees the function but the Google code won't for for it needs the page completely loaded.
How can I fix setTimeout or how can I pause the script for a number of seconds ?
Thanks!
Write
func1(cont);
as
window.setTimeout(function() {
func1(cont);
}, 1000);
Instead of declaring the function like this:
function func1(cont) {}
declare it like this:
var func1 = function(cont) {}
You'll need to rearrange your code a little:
$(document).ready(function(){
var cont = 0;
var func1;
var searchComplete = function()
{
//Some code
cont += 1;
if (cont < length ) {
func1(cont);
} else {
// Other code
}
}
func1 = function(cont)
{
//Some code here
search.setSearchCompleteCallback(this, searchComplete, null);
//Some other code
}
func1(cont);
});
I'd try something like this. I prefer to declare the vars and functions inside the jquery namespace, but you could equally move the cont variable and the functions outside of the document ready function and have them available globally.
$(document).ready(function(){
$.cont = 0;
$.func1 = function() {
//Some code here
search.setSearchCompleteCallback(this, $.searchComplete, null);
//Some other code
}
$.searchComplete = function() {
//Some code
$.cont += 1;
if (cont < length ) {
setTimeout($.func1,1000);
} else {
// Other code
}
}
setTimeout($.func1,1000); // delay the initial start by 1 second
});
Hopefully I've got your description correct:
document.ready() event fires
Inside document.ready() you want a function to be called after X milliseconds
This function wires up the Google object search.setSearchCompleteCallback() to another function (which it looks like it needs a parent object from the this)
If this is the case, why do you need any of the functions declared inside the document.ready() scope? Can you't simply make all 3 global? e.g.
var search = null; // initialise the google object
var cont = 0;
function timedSearch()
{
search.setSearchCompleteCallback(this, searchComplete, null);
}
function searchComplete()
{
if (++cont < length) // postfix it below if this is wrong
setTimeout(timedSearch,1000);
}
$(document).ready(function()
{
setTimeout(timedSearch,1000);
}
Hit me with the downvotes if I've misunderstood.