jQuery.ready and this - javascript

I have a web page that load a lot of javascript files.
Each javascript do a specific action.
I'm using this model in each javascript file:
"use strict";
$(function() {
var self = this;
// some code
var func1 = function() {
// do some action
};
var runTimer = function() {
func1();
setTimeout(self.runTimer, 60000);
}
});
BUT "this" in this case point to html document and I would like to point to the function itself.
How can I achieve it?
Is there any better "model" to use?
My webpage is like a lot of widgets running at same time and each javascript file run a specific widget.
Thank you very much.

I am not seeing a proper reason for you doing this. If you want to assign a function to a variable just use:
var functionVariable = function() { ... }
Maybe if you tell us why you want to do this out answers will be more specific.

From what you've written it looks like you want to call func1() every 60 seconds. Rather than set up a function like runTimer() that recursively calls setTimeout, just use setInterval. Rather than having the function runTimer(), just use:
var timer = setInterval(func1, 60000);
and if/when you want to cancel this and stop func1 being called, use:
clearInterval(timer);
From what I can see you're only using self/this to achieve this, and there's a better/more straightforward way of doing this. If there's another reason you want to set self=this, can you add to your code sample or try to clarify what you want to acheive?

Have a look at the proxy function: it does exactly that

Related

How to use only parenthesis without the function in javascript?

The question may not be clear, so I will clear that here. I am using require.js to import a script in script. Here is a piece of code :
var vr = {};
vr.example = function(func) {
return require(["https://example.com"], func);
};
So, now I am able to call it by :
vr.example( function() { .... });
But, I am thinking about not writing the function everytime I have to call it. I would like to write something like this :
vr.example({ ... });
And the result should be same. But I can't understand how to do it. So please help
Thanks in advance.
The thing you want can't be done in JavaScript ! But there is a way to do, by making an interpreter. Here is a basic example. I don't really recommend it, well I am showing you just a possibility ;)
window.InterpretData = function() {
var el = document.querySelectorAll("script[type='text/test']") // You can change it anyway !
for(var i = 0; i < el.length; ++i) { // You can use i++ instead of ++i, but ++i is much optimised for this function, watch out their differences in the internet.
var val = el[i].innerHTML
var crt = document.createElement("script")
crt.id = "InterpretedScript"
document.getElementsByTagName("body")[0].appendChild(crt) // Creating a new script element
val = val.replace(/\.example\(\{([\S\s]*?)\}\)/gm, function(_, a) { // Wish you are familiar with regular expressions
a = ".example( function() {" + a + "})"
document.getElementById("InterpretedScript").innerHTML += a;
}
}
}
Now you can do :
<!DOCTYPE html>
<body>
<script type="text/test">
// Defining
var vr = {};
vr.example = function(func) {
return require(["https://example.com"], func);
};
// Calling
var.example({ ... })
<script>
<script>
new InterpretData()
</script>
</body>
</html>
Output :
vr.example({ ... }) converts to vr.example( function() { ... })
Well, remember this example is just to give you an idea about a possibility to solve your problem. It's not the perfect solution though you can't again declare the "example()" to any other constant / variables, that contain different parameters ! So, the only way lies to either use ES6's fat arrows (=>) or just declare the function earlier and go on reusing it ! If you have to support old browsers than go with reusing technique shown by #mbojko, or just go with ES6's fat arrows, said earlier by #deceze. So, want do you think ?
So, you want to pass a block of code not wrapped with a function? Short answer: you can't do that in JavaScript. And require.js does expect a callback function at any rate.
If the callback function is reusable, you can declare it once and reuse it like:
function myReusableCallback(args) {
//...
}
vr.example(myReusableCallback);
And that's pretty much it.
Because the require() function returned from the vr.example() takes a callback function and since this callback function is usually provided by the invocation of vr.example, it, therefore, means you can't necessarily call it with and object as you want to. So you can only use an object if there is no callback expected by the require() an or if you have a static function that you want to be executed all the time then you can implement the function inside of the vr.example and then just pass the object which you need to use inside the function.
It's not possible because {} is not a function, it's an object.
You can try it out yourself using typeof({}) and compare it to typeof(() => {}) or typeof(function() {})

setInterval function not working

I seem to not be able to call the setInterval function like this:
this.timerHandler = setInterval(function(this.myTimerFunction){},1000)
It seems that if I make a global function and call that, the code works perfectly but it seems that calling a function locally using this, it won't work. I have tried calling this.myTimerFunction just before this line of code and it actually executes the code and works perfect, it's just that it seems it does not want to execute the function from a timer handler.
Any suggestions to try and fix this? this.myTimerFunction is a prototype function btw.
the syntax is wrong, you also have to take into account the context
var that=this; //save context
this.timerHandler = setInterval(function(){ //You can not use "this." like parameter
that.myTimerFunction(params);
},1000)
if you don't need send parameters in your function you can use
this.timerHandler = setInterval(this.myTimerFunction,1000);
setInterval takes a function and an interval.
function(this.myTimerFunction){}
should just be:
this.myTimerFunction
or
this.myTimerFunction.bind(this)
You may not need the bind if the context doesn't matter.
Try this:
this.timerHandler = setInterval(this.myTimerFunction, 1000);

Advanced javascript calling plugin function within function

(function($) {
$.fn.extend({
clock: function(options) {
var options = $.extend(defaults, options);
.......
.......
return this.each(function() {
var prev = function() {
console.log("hello world!");
alert('getweather');
};
$('#left').click(function() {alert(342);});
});
})(jQuery);
how to call the plugin functions prev and $('#left') from below code
$.fn.clock().prev(); //doesn't work
$.fn.clock('#left'); //doesn't work
thanks in advance
You cannot, based on the code provided. It is impossible. The function is assigned to the local variable prev, which is not being exposed outside the local scope in any way.
If you want to make it accessible, you need to store the function somewhere such that it won't go out of scope, and then provide some interface, typically via something like $('my-element').clock('prev'). jQuery Plugin Authoring explains best practices for exactly this, specifically under Plugin Methods.
Those are anonymous functions. Even if they were within your scope, you wouldn't be able to call them.
A workaround would be to trigger a click event on #left:
$('#left').trigger('click');

Function listener in JavaScript and/or jQuery

Wondering if there is an elegant way to listen for a function in JavaScript and/or jQuery.
Rather than listening for a $('#mything').click(function(){ //blah }) I'd like to listen for when a specific function is fired off. I don't want to edit the function as it's within a library that I don't want to hack directly.
I did find this: http://plugins.jquery.com/project/jqConnect which connects functions.
But wondering about a better technique.
The only way to do this is to override the function (ie, hack the library):
(function() {
var oldVersion = someLibrary.someFunction;
someLibrary.someFunction = function() {
// do some stuff
var result = oldVersion.apply(this, arguments);
// do some more stuff
return result;
};
})();
Edit: To run your code after the library function has run, just call the library function first, storing the result in a variable. Then, run your code, and finally return the previously stored result. I've updated my example above to accomodate running code either before or after the library function.

How do I call another function in the same javascript namespace?

I like to organize my javascript in namespace style like below. What I want to know : is there another (shorter?) way to call myFirstFunction() from mySecondFunction()? I tried this.myFirstFunction() and it's not working so maybe there's some kind of mysterious trick here that I don't know.
var myNameSpace = {
myFirstFunction: function(){
alert("Hello World!");
},
mySecondFunction: function(){
myNameSpace.myFirstFunction();
}
}
Thanks for your help as usual, people of SO! :)
As written in your example code, this.myFirstFunction() would work. Your code is likely simplified to illustrate your problem, so it would probably help to see the actual code to tell why it doesn't work with this.
One possible reason that it fails would be if the code where you call this.myFirstFunction() is inside a closure. If so, this would be a reference to the closing function, not your namespace and would therefore fail. See here for a contrived example based on your code to see what I mean. Again, having a look at the actual code would probably be helpful to diagnose what's going on.
Your suggestion to use 'this' should work. i.e.:
var myNameSpace = {
myFirstFunction: function(){
alert("Hello World!");
},
mySecondFunction: function(){
this.myFirstFunction();
}
}
Result:
myNameSpace.mySecondFunction() // "Hello World!".
If you want it to be shorter maybe you should consider the following pattern:
Javascript Design Pattern Suggestion
basically for your example:
var myNameSpace = (function()
{
function _myFirstFunction(){
alert("Hello World!");
}
function _mySecondFunction(){
_myFirstFunction();
}
return {
MyFirstFunction : _myFirstFunction,
MySecondFunction : _mySecondFunction
};
})();
I find this to be the cleanest pattern, also providing "private/public" variables in javascript that's otherwise pretty much impossible
In some cases the this keyword should work fine. If you explicitly call myNameSpace.mySecondFunction() then this.myFirstFunction() will execute as intended.
If you are using myNameSpace.mySecondFunction as an event handler it likely will not. In the case of an event handler you would need some way to refer to the namespace you want to use. A lot of JavaScript frameworks provide a way to define what the this keyword refers to. For example, in MooTools you can do myNameSpace.mySecondFunction.bind(myNameSpace) which will cause this to refer to myNameSpace inside mySecondFunction. If you are not using a framework you could make your event handler an anonymous function like:
document.getElementById('myId').addEventListener('click', function(e) {
myNameSpace.mySecondFunction.call(myNameSpace);
});
For more information on the call method I would refer to the MDC page for the call function or you could use apply which behaves similarly to call but passing an array of arguments for the second paramter rather than having a varargs like approach for additional parameters.
All of these suggestions are predicated on defining your namespace as #Harnish suggested:
var myNameSpace = {
myFirstFunction: function(){
alert("Hello World!");
},
mySecondFunction: function(){
this.myFirstFunction();
}
}
For more information about JavaScript function binding I'd highly suggest reading Justin's article on Function scope and binding in JavaScript
If you are attaching to event:
possible issue could be if you are attaching Namespace's function to event, like:
$(el).on("click", nameSpace.myFunc);
....
nameSpace = {
myFunc: function(){
this.anotherFunc();
}
}
that will throw error.
Solution 1
You may change this.anotherFunc() with nameSpace.anotherFunc()
Solution 2
You might change
$(el).on("click", nameSpace.myFunc);
// to ----->
$(el).on("click", function(){ nameSpace.myFunc(); } );

Categories

Resources