http://jsfiddle.net/hRksW/
function test() {
this.alerting = function () {
alert("test");
};
this.something = function () {
setInterval(function () {
this.alerting();
}, 1000);
};
}
var a = new test();
a.something();
Calling the function something() should call the function alerting() every second. This should alert 'test' every second. Why doesn't that happen and how can I make it happen? Note that I want to keep this design of calling a method in a method, if possible.
Store a reference of this in a variable and use it for method that run outside of the current context (like the setInterval does)
function test() {
var that = this;
this.alerting = function () {
alert("test");
};
this.something = function () {
setInterval(function () {
that.alerting();
}, 1000);
};
}
var a = new test();
a.something();
http://jsfiddle.net/N6hPB/
function test() {
this.alerting = function () {
alert("test");
};
this.something = function () {
setInterval(this.alerting, 1000);
};
}
var a = new test();
a.something();
Hope this helps! Here the timer is in ms.
function something(){
window.setInterval(alerting, 1000);
}
function alerting() {
alert('test');
}
Another way to do it is returning an object instead.
function test() {
var self = {
alerting : function () {
console.log("test");
},
something : function () {
setInterval(function () {
self.alerting();
}, 1000);
}
};
return self;
}
var a = new test();
a.something();
You can do it making an object with functions, and then call them without instantiating it.
var testCaller = {
alerting: function() {
alert("test")
},
something: function() {
// Store current scope
var self = this;
setInterval(function() {
self.alerting();
}, 1000);
}
}
testCaller.something();
You can try this code. I have tested it, and it works. In your code, "this" pointer points to somewhere else.
function test() {
test.prototype.alerting = function() {
alert("alert test");
};
test.prototype.something = function () {
setInterval(this.alerting, 1000);
};
}
var a = new test();
a.something();
Related
Given code snippet of code does not stop even though I'm using setTimeout in it.
var myObj = {
myFunc: function () {
var self = this;
var timer = setTimeout(function () {
console.log('Timeout called');
self.myFunc();
}, 100);
}
};
myObj.myFunc();
myObj = null;
Inside the setTimeout callback, the given code recursively calling myFunc (self.myFunc()), that's why it is going forever.
How can I create a custom chainable delay function in JavaScript using prototype or currying or using new keyword?
Original question is
var foo = function () {
console.log("bingo!");
};
function bar() {
console.log("Wow!");
}
// make below two lines work
foo.delay(300); // after 0.3s: "bingo!"
bar.delay(600); // after 0.6s: "Wow!"
// This returns undefined, how to fix it?
My attempt so far.
function delay(time) {
setTimeout(this, time);
}
var foo = (function () {
console.log();
console.log("bingo!");
return {
delay: delay.bind(this)
}
})();
function bar() {
console.log("Wow!");
return {
delay: delay.bind(this)
}
};
// bar.prototype.delay = function() { return console.log("bar.prototype.delay"); }
foo.delay(300); // after 0.3s: "bingo!"
bar.delay(600); // after 0.6s: "Wow!"
Lastly, can I ask you where would be a good place to study these kind of topics to be more fluent in JavaScript? Thank you in advance.
You have a problem with this code:
setTimeout(this, time); // The first param must be the function to be executed after `n` ms.
Here you need to pass the time value to the function delay, you could pass the implicit argumentsarray.
return {
delay: delay.bind(this) // Here you need to pass the `time` value.
}
This is an approach to bind the delay function.
return {
delay: delay.bind(this, function() {
console.log("Wow!");
}, ...arguments)
}
Important: You don't to bind the function delay to pass the context this value. That binding it's necessary if the function delay will use the context this.
function delay(fn, time) {
setTimeout(fn, time);
}
var foo = (function() {
return {
delay: delay.bind(this, function() {
console.log("bingo!");
}, ...arguments)
};
})();
var bar = (function() {
return {
delay: delay.bind(this, function() {
console.log("Wow!");
}, ...arguments)
};
})();
// bar.prototype.delay = function() { return console.log("bar.prototype.delay"); }
foo.delay(300); // after 0.3s: "bingo!"
bar.delay(600); // after 0.6s: "Wow!"
I am trying to call a function from inside a timed function called by setInterval().
Here is my code:
export class SmileyDirective
{
FillGraphValues()
{
console.log("FillGraphValues works"); // this works
}
MyTimer()
{
console.log("timer works"); // this works
this.FillGraphValues(); // this does not work
FillGraphValues(); // this does not work
}
draw()
{
this.FillGraphValues(); // this works
setInterval(this.MyTimer, 1000);
}
}
The App crashes with either:
"this.FillGraphValues is not a function"
or
Cannot find name 'FillGraphValues'. Did you mean the instance member 'this.FillGraphValues'?
I even tried:
setInterval(function(){MyTimer()}, 1000);
and
setInterval(function(){this.MyTimer()}, 1000);
But they didn't work.
Many Thanks :)
Maybe this would work:
setInterval(() => {this.MyTimer()}, 1000);
so code looks like this :
export class SmileyDirective {
FillGraphValues() {
console.log("FillGraphValues works"); // this works
}
MyTimer() {
console.log("timer works"); // this works
this.FillGraphValues(); // this DOES work
}
draw() {
this.FillGraphValues(); // this works
setInterval(() => { this.MyTimer() }, 1000);
}
}
var obj = new SmileyDirective();
obj.draw();
this transpiles cleanly to:
define(["require", "exports"], function (require, exports) {
"use strict";
var SmileyDirective = (function () {
function SmileyDirective() {
}
SmileyDirective.prototype.FillGraphValues = function () {
console.log("FillGraphValues works"); // this works
};
SmileyDirective.prototype.MyTimer = function () {
console.log("timer works"); // this works
this.FillGraphValues(); // this does not work
};
SmileyDirective.prototype.draw = function () {
var _this = this;
this.FillGraphValues(); // this works
setInterval(function () { _this.MyTimer(); }, 1000);
};
return SmileyDirective;
}());
exports.SmileyDirective = SmileyDirective;
var obj = new SmileyDirective();
obj.draw();
});
The part to notice is
var _this = this;
this.FillGraphValues(); // this works
setInterval(function () { _this.MyTimer(); }, 1000);
which essentially preserves the context by saving the this variable in closure and using it when the setInterval invokes the function.
I have a function like this :
$.SetInLocalStorageVideoTime = function (uuid) {
alert(uuid);
var Interval = setInterval(function () {
localStorage.setItem('poption-ctime-'+ uuid , jwplayer("target").getPosition());
},10000);
var ClearInterVal = clearInterval(Interval);
return {
Interval : Interval,
ClearInterVal : ClearInterVal
}
};
My problem is how to call the Interval function and pass uuid param to that.
I have tried $.SetInLocalStorageVideoTime("blahblah").Interval(); but it throws an error.
var Interval = setInterval(...)
This immediately calls the setInterval function and assigns its return value to Interval; same for clearInterval. You don't want to call the function, you want to create a function which when called calls the function. Two ways to do that:
var Interval = function () {
setInterval(...);
}
var Interval = setInterval.bind(null, ...);
Putting it all together, you want this:
$.SetInLocalStorageVideoTime = function (uuid) {
var interval = null;
var set = function () {
interval = setInterval(function () {
localStorage.setItem('poption-ctime-'+ uuid , jwplayer("target").getPosition());
}, 10000);
};
var clear = function () {
clearInterval(interval);
};
return {
Interval : set,
ClearInterVal : clear
}
};
Look this plunker : https://plnkr.co/edit/7H61Vv6m8M552CNeIpSA?p=preview
You must encapsulate into function :
var stop;
var interval = function () {
stop = setInterval(function () {
console.log(uuid);
},100);
}
var ClearInterVal = function () { clearInterval(stop) };
You have several simple issues, you must export function that will clearTimeout
$.SetInLocalStorageVideoTime = function(uuid) {
// auto start interval, you could
// add starter function or something
var Interval = setInterval(function() {
localStorage.setItem('poption-ctime-' + uuid, jwplayer("target").getPosition());
}, 10000);
// clear function
// exported
var ClearInterVal = function() {
if (Interval)
clearInterval(Interval);
}
return {
// Interval is not required here
ClearInterVal: ClearInterVal
}
};
$.SetInLocalStorageVideoTime();
I have this Javascript class:
function PageManager () {
this.timeoutHandler = function () {
alert ("hello");
}
this.startTimeout = function () {
this.timeout = setTimeout ("this.timeoutHandler()", 1000);
}
}
When I call obj.startTimeout (); I get this error:
this.timeoutHandler is not a function
How do I call a class function in the timeout?
If you pass a string to setTimeout, the code is evaluated in the global scope. Always pass a function reference:
this.startTimeout = function () {
var self = this;
this.timeout = setTimeout(function() {
self.timeoutHandler();
}, 1000);
}
Or if you don't need a reference to the object inside timeoutHandler, then you can pass the function directly:
this.timeout = setTimeout(this.timeoutHandler, 1000);
The problem is that you're passing setTimeout a string. This string is eval'd, with a scope of the window. So if you were to do this:
this.timeout = setTimeout ("console.log(this);", 1000);
... with Firebug installed, you'd see that this is window, which does not have a timeoutHandler method, of course.
This is why you should never, ever pass setTimeout a string. Give it a function reference instead.
function PageManager () {
this.timeoutHandler = function () {
alert ("hello");
console.log(this);
}
this.startTimeout = function () {
this.timeout = setTimeout (this.timeoutHandler, 1000);
}
}
obj = new PageManager ();
obj.startTimeout();
When you execute this code, you'll have the scope you're expecing.