Test in JavaScript - javascript

Can you help me please?
During a test, I did not understand this question:
Given the following code, write two lines of JavaScript to call the
print() function in a way that prints the Window global object in the
JavaScript console?
Your code must not use the variable window. Feel free to comment.
Printer = function(){
this.print = function() {
console.log(this);
}
}
var printer = new Printer();

Answer:
printer.print.call(this);
//or
printer.print.bind(this)();
Why this is usefull:
Example: adding an event listener in an object:
function person(){
this.clicker=0;
document.body.addEventListener("click",function(){
this.clicker++;
});
}
So this should work, shouldnt it? Nope it doesnt, cause the eventlistener automatically binds this as the clicked element. So this will be body, wich hasnt a clicker property. So in that situation its usefull to override this...
document.body.addEventListener("click",function(){
this.clicker++;
}.bind(this))
Or in newer browsers (see arrow funcs):
document.onclick=()=>{
this.clicker++;
};
Thats what the tutorial wants to tell you. Hope it helps...

Related

Understanding jQuery & Pub Sub Pattern with this example

I use jQuery for some time, but that is usually very simple jQuery. I just watched some video tutorial in which the author uses something called Pub Sub Pattern. I've never heard of it before, so I have searched on Stackoverflow and Google for explanations:
Why would one use the Publish/Subscribe pattern (in JS/jQuery)?
But it's still not clear to me, especially because of the code that is used by the author of the above mentioned tutorial. So, I will paste this code here and if you can give me explanations:
1. Here is the first .js file named pubsub.js, and I don't understand it:
(function($) {
var o = $({}); // ??? what is this ???
$.subscribe = function() { // ??? and this ???
o.on.apply(o, arguments); // ??? o.on.apply(o, arguments) ???
};
$.unsubscribe = function() { // ??? and this ???
o.off.apply(o, arguments); // ??
};
$.publish = function() { // ??? and this ???
o.trigger.apply(o, arguments); // ?? o.trigger.apply(o, arguments); ??
};
}(jQuery));
I know that with jQuery you can use $( document ).ready() or $(function() but I've never seen (function($) { ... }(jQuery)); - what does this mean/do? Also, I don't understand the rest of the code...
2. The next file is app.js and it contains:
(function() {
$.subscribe('form.submitted', function() {
$('.flash').fadeIn(500).delay(1000).fadeOut(500);
})
});
What does this actually do? Again, what (function() { ... }); means/do? And as for the rest of code, can you explain to me $.subscribe('form.submitted', function() {?
3. Finally, we have something like this:
$.publish('form.submitted', form); // publish?
This also is not clear to me.
I understand that all this is a basic implementation of PubSub Pattern with jQuery, but I still don't get why would someone do in this way (by using this pattern), I have read that answer on Stackoverflow, but it's still unclear to me... I guess that if I understand this code, then it would become clearer to me why and when to use this pattern.
In the case of (function($) { ... }(jQuery));, the author is passing the jQuery instance in as a parameter. Inside the function (which has it's own scope), the $ is a reference to the jQuery instance that was passed in.
"Pub Sub" is just another term for Event Management, or Event Handling. All you're saying is "When [this] happens, do [that]".
When you "subscribe", you are passing in 2 parameters, the "event" that you are listening for, and the code you want to run when the event "fires".
When you "publish", you are "firing" (or triggering) that event.
Think of it like the onclick event. When you set something up on the onclick event, you are subscribing to that event. When you click, you are publishing that event.

Problems calling a function inside a listener (onClick)

I've looked around on here for an answer to this but I can't find anything that works.
Basically I'm making a tower defence game. Each tower is dynamically created and is onClick enabled. Inside the onClick listener I am trying to call a method within the class.
e.g a player clicks the tower and can choose upgrades
However the method within the listener is outputing undefined function. I know this is clearly something to do with my scope. But I can't figure out what I'm missing?
Surely it should be something like:
someListener: function(){
this.game.doSomeOtherFunction();
}
I've tried a console.log and someListener is definitely being called, but the method inside is undefined.
Thanks,
Its not working because this changes context accordingly within a callback. You can do something like this:
var self = this;
...
someListener: function(){
self.game.doSomeOtherFunction();
}
...
Or simply you could also do this:
someListener: (function () {
var callback = function(){
this.game.doSomeOtherFunction();
}
return callback.bind(this);
}())
I hope it helps.

onclick attribute doesn't find global function

I dinamically add divs with onlick event, but clicking got an error (Mozilla Firefox): "ReferenceError: myfoo is not defined". If I change onclick event to alert, it works fine, but non with mysefl written functions.
Here is jsfiddle
http://jsfiddle.net/UJ85S/5/
function myfoo(x)
{
alert(x);
}
$("#some").html('<div id="cool_div" onclick="myfoo('+"'xwe'"+');"></div>');
Can you, please, explain what is wrong?
(I understant that can assign.click event, but is it possible through onclick?).
What you really need to do is not let jsFiddle wrap it inside the onload event as this uses a function which creates new scope. Your function is then not accessible outside this new scope. Learn what's happening not learn how to get around it (i.e. not just hack your code to the window Object):
http://jsfiddle.net/UJ85S/12/
No wrap - in <body>
This is happening because you define myfoo inside of $(window).load(function () {...}) function (JSFIDDLE does this):
You need to declare a global function. You can do window.myfoo to declare your function instead.
window.myfoo = function (x)
{
alert(x);
}
JSFIDDLE
But yeah, it's not a good practice to polute the global scope, that's why it's better to use $(...).on("click", function () { alert(...) }) handlers.
I discourage using on... attributes in HTML because it's also another bad practice.
Your code becomes:
function myfoo (x)
{
alert(x);
}
var $divToAppend = $("<div id='cool_div'>")
$divToAppend.on("click", function () {
myfoo("hello");
});
$("#some").html($divToAppend);
And here a DEMO.

Why does "this.myFunction" not work when calling a function inside an object?

Here are two samples of code. The first one does not work and the second one does, though I'm completely at a loss as to why. Can someone explain this?
[I'm writing a simple game using a bit of jQuery to be played in a webkit browser (packaged with Titanium later).]
In the first example, Firebug tells me that "this.checkCloud" is not a function.
function Cloud(){
this.checkCloud = function(){
alert('test');
}
$("#"+this.cloudName).click(function(){
this.checkCloud();
});
}
...but then this works:
function Cloud(){
this.checkCloud = function(){
alert('test');
}
var _this = this;
$("#"+this.cloudName).click(function(){
_this.checkCloud();
});
}
This one works perfect.
Why does the first one not work? Is it because "this.checkCloud" is inside of the anonymous function?
in this example:
$("#"+this.cloudName).click(function(){
this.checkCloud();
});
this referrers to the element selected(jquery object).
what you can do is use private functions
var checkCloud = function(){
alert('test');
}
this way you can simply call it inside your anonymous function
$("#"+this.cloudName).click(function(){
checkCloud();
});
That is because the meaning of this can potentially change each time you create a new scope via a function. The meaning of this depends on how the function is invoked (and the rules can be insanely complicated). As you discovered, the easy solution is to create a second variable to which you save this in the scope where this has the expected/desired value, and then reuse the variable rather than this to refer to the same object in new function scopes where this could be different.
Try this:
function Cloud(){
this.checkCloud = function(){
alert('test');
}
var func = this.checkCloud;
$("#" + this.cloudName).click(function(){
func();
});
}
When you assign an even listener to an element, jQuery makes sure that this will refer to the element. But when you create the _this variable, you're creating a closure that jQuery couldn't mess with, even if it wanted to.

Unable to re-define a function in my javascript object

I have an object defined using literal notation as follows (example code used). This is in an external script file.
if (RF == null) var RF = {};
RF.Example= {
onDoSomething: function () { alert('Original Definition');} ,
method1 : function(){ RF.Example.onDoSomething(); }
}
In my .aspx page I have the following ..
$(document).ready(function () {
RF.Example.onDoSomething = function(){ alert('New Definition'); };
RF.Example.method1();
});
When the page loads the document.ready is called but the alert('Original Definition'); is only ever shown. Can someone point me in the right direction. I basically want to redefine the onDoSomething function. Thanks, Ben.
Edit
Thanks for the comments, I can see that is working. Would it matter that method1 is actually calling another method that takes the onDoSomething() function as a callback parameter? e.g.
method1 : function(){
RF.Example2.callbackFunction(function() {RF.Example.onDoSomething();});
}
Your code as quoted should work (and does: http://jsbin.com/uguva4), so something other than what's in your question is causing this behavior. For instance, if you're using any kind of JavaScript compiler (like Closure) or minifier or something, the names may be being changed, which case you're adding a new onDoSomething when the old one has been renamed. Alternately, perhaps the alert is being triggered by something else, not what you think is triggering it. Or something else may have grabbed a reference to the old onDoSomething (elsewhere in the external script, perhaps) and be using it directly, like this: http://jsbin.com/uguva4/2.
Thanks for the response .. in the end the answer was unrelated to the code posted. Cheers for verifying I wasn't going bonkers.

Categories