Value unchanged when another function is called in javascript - javascript

I was reading an article. It is related to javascript. Here, is a code sample from the article. Please look at below.
function customobject(){
this.value = 2;
}
customobject.prototype.inc = function(){
this.value++;
}
function changer(func){
func();
}
var o = new customobject();
alert(o.value);
o.inc();
alert(o.value);
changer(o.inc);
alert(o.value);
My question is Why is the value for "o.value" unchanged when changer(o.inc) is called ?

o.inc is just a reference to the anonymous function:
function() {
this.value++;
}
Whereas this is the scope in which the function is executed. So when you run changer(o.inc), this is actually pointing to the global, in browsers it's window. It doesn't necessarily have anything to do with o.
You could bind the scope like this:
function changer(func, scope){
func.call(scope); // or apply
}
changer(o.inc, o);
Or simply:
function changer(func){
func();
}
changer(o.inc.bind(o));

The problem is because Function does not save instance for objects. You have to pass the object as argument so call your function, like this.
function customobject(){
this.value = 2;
}
customobject.prototype.inc = function(){
this.value++;
}
function changer(o){
o.inc();
}
var o = new customobject();
console.log(o.value); //It has to print 2
o.inc(); //Increment to 3
console.log(o.value); //It has to print 3
changer(o); //Increment to 4
console.log(o.value); //It has to print 4

Related

JS "as soon as" condition

I've got a small problem (kind of a problem with curiosity actually). Is it possible to create some condition when if the condition is satisfied, the appropriate code is executed? Without use of setInterval and setTimeout of course. Or callback? Maybe AJAX?
var x;
if (x != "undefined") {
//code to be executed
}
setTimeout(function() { x = 3.14; }, 5000);
//after those let's say 5 seconds (the time is random) x becomes defined and the code above is executed
Thanks!
If you're ok with wrapping x inside an object, you can try using setter pattern:
var obj = {};
Object.defineProperty(obj, 'x', { set: function(xval) { /* do stuff; */ } });
// some time later in the code ...
obj.x = somevalue
// do stuff will fire
Or, in the object initializer:
var obj = {
set x(xval) {
// do stuff;
}
}
// some time later in the code...
obj.x = somevalue
// do stuff will fire
Note that the only (but optional) value we can explicitly pass to the callback is the value we set the bound property to (the value of x). (Of course, you can reference anything that obj's scope can see).
See also: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/set
when a function depends on another one, I just do a simple callback.
var x;
function check_and_wait(callback) {
if (x != undefined) {
callback();
}
}
check_and_wait(function() {
//code goes here
});
A possible solution using promises:
var x;
var promise = new Promise(function(resolve,reject) {
setTimeout(function() {
x = 3.15;
resolve();
},3000)
});
promise.then(function(){
console.log("code to be executed")
console.log(x)
});

Why this "this" behavior?

Hello I am stuck on a case I don't get
here is the code
function car(speed) {
this.speed = speed;
this.accelerate = function() {
this.speed += 1;
}
}
var oldcar = new car(1);
function test(cb){
cb();
}
test(oldcar.accelerate);
console.log(oldcar.speed);
// 1
test(function(){ oldcar.accelerate(); });
console.log(oldcar.speed);
// 2
On the first function call test(), I observe that the this in the oldcar.accelerate method is set to window.
On the second case, the this is correctly set to oldcar.
I don't understand how calling test() with oldcar.accelerate instead of function(){ oldcar.accelerate(); } make such a difference.
Can someone explain the behavior ? thanks !
Because when you pass a method as a callback you are passing only the method, not the object which it belongs to.
When this is used in without any given scope, it defaults to window (or the closest surrounding scope).
A correct way is to pass the entire object, or an anonymous function has has access to the entire object..
function test(cb){
cb();
}
test(function(){ oldcar.accelerate() });

JS Function returning function for later use - arguments undefined

I am trying to create a function that can then return many functions based on an input. Here is an example of the problem I am facing.
var giveFunction = function(text) {
return function(text) {
console.log(text)
}
}
var test = giveFunction('this is a test');
test()
Running test() at the end prints undefined instead of 'this is a test.' Is there any way around this problem?
The inner function should not contain any parameter,
var giveFunction = function(text) {
return function() {
console.log(text)
}
}
Let it create a closure. If it has a parameter then that would be read during execution and undefined would be printed as you are not calling that function with any arguments.
If you want your code to be working then you have to use bind for that,
var giveFunction = function(text) {
return function(text) {
console.log(text)
}.bind(null, text)
}
var test = giveFunction('this is a test');
test(); //'this is a test'
Lets go one step further and ask why?
var outerFunction = function(outerParameter) {
return innerFunction function(innerParameter) {
// in here we have access to anything in this function and the outer function
// all the way to out the the global scope
// therefore, we dont need to pass innerParameter in again as a parameter! ( in your case we 'next')
}
/// now over here, outside of innerFunction, we do NOT have access to innerParameter!
}
So applying the above principles to your code we have:
var giveFunction = function(text) {
return function() {
console.log(text)
}
}
var test = giveFunction('this is a test');
test()
which now works!
Finally, checkout the most upvoted post under the javascript tag:
How do JavaScript closures work?

setInterval inside a return function does not work

I have a code similar to the below.
function test(){
return function(){
setInterval(//Another Function Reference // ,1000);
}
}
I am calling test()();
I see the above code not working. Could someone please explain me why?
There is no closure in your code1. test returns a function object, but that [function] is not executed. In the snippet, 3 closures are used in the inner function, the returned function object is assigned to a variable, and that is executed. The advantage of returning a function object is that you can assign it to different values and execute them separately.
1 Earlier version of the question mentioned 'closure not working'
// startInterval: interval 1 second, message: 'Hello' (default)
var startInterval = test(null, 1000);
// anotherInterval: interval 5 seconds, message: ''Hello to you too''
var anotherInterval = test('<i>Hello to you too</i>', 5000);
// execute the function objects
startInterval();
anotherInterval();
// [hithere], [time] and [result] are closed over
function test(hithere, time){
hithere = hithere || 'Hello';
time = time || 1000;
var result = document.querySelector('#result');
return function(){
setInterval(function(){
result.innerHTML += hithere+'<br>';
},time || 1000);
}
}
<div id="result">Greetings!<hr></div>
function test(){
return function(){
setInterval(function(){
alert("Hello");
},1000);
}
}
var hello = test();
hello();
It seems to be working fine. Remember that if you call test(), you just get the function back, but you haven't run it. To run it, you need to call the resulting function. You can do this by either:
test()();
Or:
var myFunction = test();
myFunction();
It is working for me... you are returning a function so you will need to invoke this:
http://jsfiddle.net/97hzj2je/
function test(){
return function(){
setInterval(function(){
alert("Hello");
},1000);
}
}
test()();
I assume you are wanting test() to be a self invoking function so the return function is set once so instead do:
http://jsfiddle.net/LL24g8z2/
var test = (function(){
return function(){
setInterval(function(){
alert("Hello");
},1000);
}
})();
test();
bind your inner function to the context, the problem is that when the set interval is finally being executed it is in the global scope and not in the one that you called it from. Can be fixed like this:
function test(){
return function(){
setInterval(/*Another Function Reference */ ,1000);
}.bind(this)
}

Calling a variable variable as a function in jquery

Just like in the PHP I need a variable variable.
I`m getting a data-type from the html and that variable is actually a function in the js code.
And I get it I need to call it.
Every time its different, so I don`t know which one exactly is.
if (e.which == 114 || e.which == 116) {
var action = $('.active').data("action");
action();
}
function testing() {
alert('yes');
}
Here the function name is testing.And the variable action is holding it.
How I`m suppose to call it ?!
I remember that there was a easy syntax for that,but I cant find it.
Thanks
You could extract the value and use eval().
<div id="something" data-action="alert('test')">SOME DIV</div>
$(document).ready(function() {
var $myObject = $("#something");
var action = $myObject.data('action');
$myObject.click(function() {
eval(action);
});
});
Try it yourself on jsfiddle
However, eval is evil
It depends on the object which holds the function. For the global scope use : window[action](). Otherwise, replace window with the name of your object : myObject[action](). However, this solution is not suitable for functions declared inside a private scope :
function f(fnName) {
function a() { alert('a') };
function b() { alert('b') };
fnName(); // error
}
In this case, you could use eval like this (⚠ keep control over inputs ⚠) :
function f(fnName) {
function a() { alert('a') };
function b() { alert('b') };
eval(fnName)();
}
Otherwise you could wrap them inside an object like so :
function f(fnName) {
var wrapper = {};
wrapper.a = function () { alert('a') };
wrapper.b = function () { alert('b') };
wrapper[fnName]();
}
f('a'); // alerts "a"
f('b'); // alerts "b"

Categories