Why can I not successively increment a variable within a function? - javascript

I'm trying to add 10 over and over for every invocation of d. It stays 20 every time, why?
function d() {
var c = [10];
c[0] += 10;
alert(c[0]); // always 20
}
d(); d(); d(); // supposed to be 20, 30, 40...

You create a new array and assign it to c each time the function is called. That resets it.
Move the assignment so it is outside the function (so it only runs once).
var c = [10];
function d() {
c[0] += 10;
alert(c[0]);
}
d(); d(); d(); // will be 20, 30, 40...
But globals are good source of bugs, so it is considered good style to wrap such things in closures to minimise the use of globals.
var d =(function () {
var c = [10];
function d() {
c[0] += 10;
alert(c[0]);
};
return d;
})();
d(); d(); d();

#Quentin already explained the reason for your problem and provided a solution. For more information about variable scope, have a look at the MDN JavaScript Guide.
As an alternative, you can assign the value to a property of the function:
function d() {
var c = d.c || (d.c = [0]); // initialize property if not set
c[0] += 10;
alert(c[0]);
}

What you have is local variable. Which gets initialized to 10 every time you invoke the function.
Try using global variable as
var c = [10];
function d() { c[0] += 10; alert(c[0]); // always 20 }

Why not just
var c = 10;
function d(){
c+=10;
alert(c);
}
d();d();d();

Related

Using a constant to define a function within a function?

Main questions:
1. How does f refer to r and t within the formula but no declaration for them anywhere in the code. Also the references appear to be cyclical.
2. Why is f2 set to f(x) what does that accomplish?
let x = 3;
let y = 7;
const f = function(r) {
return function(t) {
return x + y + Math.abs(r) + t;
}
};
const f2 = f(x);
x = 2;
alert(f2(17));
This code works but I do not understand what it is doing.
Thank you for your help.
How does f refer to r and t within the formula but no declaration for them anywhere in the code.
You can declare variables using function arguments. This is what they are doing here.
A simplified example:
function example(f) {
console.log("f is " + f);
}
example("one");
example(2);
Why is f2 set to f(x) what does that accomplish?
It calls f(x) and assigns its return value.
That return value is the function after the return keyword.
Now f2 is a function.
See also How do closures work

passing variables from 2 different functions to one other function in Javascript

I am writing a javascript programme which involves passing values between functions.
I have 3 functions called A,B and total and want to pass variable values from A and B into total.
function a() {
var result = 10;
total(result);
}
function b() {
var result1 = 20;
total(result1);
}
function total(r1, r2) {
var x = r1;
var y = r2;
console.log(x + y);
//remaining logic will go here
}
a();
b();
total();
For testing purposes i am only logging values from function a and b. But it is only getting value r1 from function a but fails for r2 from function b and says that r2 is not defined. I think it can only do one function at a time but I want it to get values from both a and b.
Try adding the variables at the top of your page then when they are used by your function they will be edited as your code runs through
function a(){
var result = 10;
total.a = result;
}
function b(){
var result = 20;
total.b = result;
}
var total = {
a: 0,
b: 0,
getTotal: function(){
console.log(total.a + total.b);
}
}
a();
b();
total.getTotal();
jsfiddle

Two operation in one function

function test(a, b){
a = a + 2;
b = b + 5;
}
var a = 1;
var b = 2;
test(a, b);
console.log(a);
console.log(b);
This return 1 and 2, but i would like 3 and 7.
Is possible to make two operation in one function? This working if i use return, but how to use return to two operation?
live: http://jsfiddle.net/anCq6/
The reason you are getting 1 and 2 instead of 3 and 7 is because there are two different a and b variables. There's the a and b you declared outside the function, and there is the a and b which represent the values you passed into the function. (Basically, the parameters declared in the function's parentheses are newly declared variables.)
If you want to change the external a and b, change your test function to the following:
function test(x, y) {
a = x + 2;
b = y + 5;
}
Or, alternatively, don't pass a reference into the function, so that the a and b in the inner scope refer to the same a and b as the outer scope:
function test() {
a = a + 2;
b = b + 5;
}
Just send it back as an object...
function test(a, b){
a = a + 2;
b = b + 5;
return {a:a,b:b};
}
var a = 1;
var b = 2;
var test = test(a, b);
alert(test.a);
alert(test.b);
DEMO HERE
This doesn't work because since numbers are passed by value and not by reference, you're modifying the local copies of those variables, however the ones in the outer scope remain unmodified.
If you remove the a and b parameters from your function, you'll get the behavior that you want since the a and b parameters that are being modified will be the ones in the outer scope.
What are references?
Here's a pretty decent answer - Javascript by reference vs. by value
In short, only objects and arrays are passed by reference. Although in reality it's more complex than this depending on how functions are defined and syntax, at this point you can assume that anything that's defined by calling new or the syntactic shorthands [] ( array ) and {} ( object ) are passed by reference. Other types like numbers and strings are passed by value.
Another solution: because of how variable scope works in JavaScript, you can just remove the parameters of "test" function and it will work.
function test(){
a = a + 2;
b = b + 5;
}
function test(){
a = a + 2;
b = b + 5;
}
var a = 1;
var b = 2;
test();
console.log(a);
console.log(b);

why is this referring to window object?

var x = 5,
o = {
x: 10,
doIt: function doIt(){
var x = 20;
setTimeout(function(){
alert(this.x);
}, 10);
}
};
o.doIt();
Why is this referring to window object rather than o. I am inside the object o context, so it should print me 10 right?
The anonymous function is executed after 10ms, and the execution context is not in o at that time.
Check out the answers to How do JavaScript closures work?
var x = 5,
o = {
x: 10,
doIt: function doIt(){
var x = 20;
setTimeout(function(){
alert(this.x);
}, 10);
}
};
o.doIt();
All functions passed into setTimeout() are executed in the global scope. The value is 5 because this.x is the same as window.x
To make this alert 20, change this.x to simply x.

JavaScript override methods

Let's say you have the below code:
function A() {
function modify() {
x = 300;
y = 400;
}
var c = new C();
}
function B() {
function modify(){
x = 3000;
y = 4000;
}
var c = new C();
}
C = function () {
var x = 10;
var y = 20;
function modify() {
x = 30;
y = 40;
};
modify();
alert("The sum is: " + (x+y));
}
Now the question is, if there is any way in which I can override the method modify from C with the methods that are in A and B. In Java you would use the super-keyword, but how can you achieve something like this in JavaScript?
Edit: It's now six years since the original answer was written and a lot has changed!
If you're using a newer version of JavaScript, possibly compiled with a tool like Babel, you can use real classes.
If you're using the class-like component constructors provided by Angular or React, you'll want to look in the docs for that framework.
If you're using ES5 and making "fake" classes by hand using prototypes, the answer below is still as right as it ever was.
JavaScript inheritance looks a bit different from Java. Here is how the native JavaScript object system looks:
// Create a class
function Vehicle(color){
this.color = color;
}
// Add an instance method
Vehicle.prototype.go = function(){
return "Underway in " + this.color;
}
// Add a second class
function Car(color){
this.color = color;
}
// And declare it is a subclass of the first
Car.prototype = new Vehicle();
// Override the instance method
Car.prototype.go = function(){
return Vehicle.prototype.go.call(this) + " car"
}
// Create some instances and see the overridden behavior.
var v = new Vehicle("blue");
v.go() // "Underway in blue"
var c = new Car("red");
c.go() // "Underway in red car"
Unfortunately this is a bit ugly and it does not include a very nice way to "super": you have to manually specify which parent classes' method you want to call. As a result, there are a variety of tools to make creating classes nicer. Try looking at Prototype.js, Backbone.js, or a similar library that includes a nicer syntax for doing OOP in js.
Since this is a top hit on Google, I'd like to give an updated answer.
Using ES6 classes makes inheritance and method overriding a lot easier:
'use strict';
class A {
speak() {
console.log("I'm A");
}
}
class B extends A {
speak() {
super.speak();
console.log("I'm B");
}
}
var a = new A();
a.speak();
// Output:
// I'm A
var b = new B();
b.speak();
// Output:
// I'm A
// I'm B
The super keyword refers to the parent class when used in the inheriting class. Also, all methods on the parent class are bound to the instance of the child, so you don't have to write super.method.apply(this);.
As for compatibility: the ES6 compatibility table shows only the most recent versions of the major players support classes (mostly). V8 browsers have had them since January of this year (Chrome and Opera), and Firefox, using the SpiderMonkey JS engine, will see classes next month with their official Firefox 45 release. On the mobile side, Android still does not support this feature, while iOS 9, release five months ago, has partial support.
Fortunately, there is Babel, a JS library for re-compiling Harmony code into ES5 code. Classes, and a lot of other cool features in ES6 can make your Javascript code a lot more readable and maintainable.
Once should avoid emulating classical OO and use prototypical OO instead. A nice utility library for prototypical OO is traits.
Rather then overwriting methods and setting up inheritance chains (one should always favour object composition over object inheritance) you should be bundling re-usable functions into traits and creating objects with those.
Live Example
var modifyA = {
modify: function() {
this.x = 300;
this.y = 400;
}
};
var modifyB = {
modify: function() {
this.x = 3000;
this.y = 4000;
}
};
C = function(trait) {
var o = Object.create(Object.prototype, Trait(trait));
o.modify();
console.log("sum : " + (o.x + o.y));
return o;
}
//C(modifyA);
C(modifyB);
modify() in your example is a private function, that won't be accessible from anywhere but within your A, B or C definition. You would need to declare it as
this.modify = function(){}
C has no reference to its parents, unless you pass it to C. If C is set up to inherit from A or B, it will inherit its public methods (not its private functions like you have modify() defined). Once C inherits methods from its parent, you can override the inherited methods.
the method modify() that you called in the last is called in global context
if you want to override modify() you first have to inherit A or B.
Maybe you're trying to do this:
In this case C inherits A
function A() {
this.modify = function() {
alert("in A");
}
}
function B() {
this.modify = function() {
alert("in B");
}
}
C = function() {
this.modify = function() {
alert("in C");
};
C.prototype.modify(); // you can call this method where you need to call modify of the parent class
}
C.prototype = new A();
Not unless you make all variables "public", i.e. make them members of the Function either directly or through the prototype property.
var C = function( ) {
this.x = 10 , this.y = 20 ;
this.modify = function( ) {
this.x = 30 , this.y = 40 ;
console.log("(!) C >> " + (this.x + this.y) ) ;
} ;
} ;
var A = function( ) {
this.modify = function( ) {
this.x = 300 , this.y = 400 ;
console.log("(!) A >> " + (this.x + this.y) ) ;
} ;
} ;
A.prototype = new C ;
var B = function( ) {
this.modify = function( ) {
this.x = 3000 , this.y = 4000 ;
console.log("(!) B >> " + (this.x + this.y) ) ;
} ;
} ;
new C( ).modify( ) ;
new A( ).modify( ) ;
new B( ).modify( ) ;
test it here
You will notice a few changes.
Most importantly the call to the supposed "super-classes" constructor is now implicit within this line:
<name>.prototype = new C ;
Both A and B will now have individually modifiable members x and y which would not be the case if we would have written ... = C instead.
Then, x, y and modify are all "public" members so that assigning a different Function to them
<name>.prototype.modify = function( ) { /* ... */ }
will "override" the original Function by that name.
Lastly, the call to modify cannot be done in the Function declaration because the implicit call to the "super-class" would then be executed again when we set the supposed "super-class" to the prototype property of the supposed "sub-classes".
But well, this is more or less how you would do this kind of thing in JavaScript.
HTH,
FK
function A() {
var c = new C();
c.modify = function(){
c.x = 123;
c.y = 333;
}
c.sum();
}
function B() {
var c = new C();
c.modify = function(){
c.x = 999;
c.y = 333;
}
c.sum();
}
C = function () {
this.x = 10;
this.y = 20;
this.modify = function() {
this.x = 30;
this.y = 40;
};
this.sum = function(){
this.modify();
console.log("The sum is: " + (this.x+this.y));
}
}
A();
B();

Categories

Resources