I've been my banging head against the wall with the above question. Let's say I have the following class:
function Counter() {...}
so when I call the constructor:
var c= new Counter();
console.log(c); //return 0
furthermore If I created the following method:
Counter.prototype.increment = function() {
return this += 1;
};
it should increment c by 1 for every call
c.increment(); // return c=1
c.increment(); // return c=2
so far I have come up with:
function Counter(){return Number(0)}
but still returns Number{} not a zero...
Any thoughts?
Thanks in advance!
JavaScript doesn't allow for a custom Object type to directly imitate a primitive value. It also doesn't allow this to be assigned a new value.
You'll have to instead store the value within a property:
function Counter() {
this.value = 0;
}
var c = new Counter();
console.log(c); // Counter { value: 0 }
And, increment the value from it:
Counter.prototype.increment = function () {
this.value += 1;
};
c.increment();
console.log(c.value); // 1
Though, you can at least specify how the object should be converted to a primitive with a custom valueOf() method:
Counter.prototype.valueOf = function () {
return this.value;
};
console.log(c.value); // 1
console.log(c + 2); // 3
You can't return a value from the constructor because you instantiate it using the new keyword, this gives you a new instance of the object.
Store a property and increment that instead:
function Counter() {
this.count = 0;
}
Counter.prototype.increment = function() {
this.count++;
return this.count;
};
var c= new Counter();
console.log( c.increment() ); // 1
console.log( c.increment() ); // 2
console.log( c.increment() ); // 3
This is your problem:
Counter.prototype.increment = function() {
return this += 1;
};
this is an object, += is not defined for objects.
Related
I need to have multiple counters so I created a function, the problem is that I can't store the value in the variable outside the function. I thought this would be easy but I couldn't find anything online.
myCounter = 2;
function count(counter) {
counter++;;
}
count(myCounter);
I would get the value in myCounter to update every time I call the function, thanks for any help you can provide
You can use a closure function that returns an object with a getter so you can initialize as many individual instances as you need
function counter() {
let _count = 0;
return {
get count() {
return ++_count;
}
}
}
let ct1 = new counter();
console.log('ct1', ct1.count, ct1.count)
let ct2 = new counter();
console.log('ct2', ct2.count, ct2.count, ct2.count)
Try this.
var myCounter = 2;
var myCounter2 = 3;
function count(counter) {
return ++counter;
}
myCounter = count(myCounter);
myCounter2 = count(myCounter2);
console.log('myCounter: ' + myCounter);
console.log('myCounter2: ' + myCounter2);
I am struggling to understand how variables are referenced and stay alive in Javascript. In the following I have two types of object, a Note and an IntervalBuilder which takes a Note and creates
a second Note.
function Note() {
this.key = 1 + Math.floor( Math.random() * 13); // from 1 to 13 inclusive
this.setKey = function setKey(i) { key = i; };
this.getKey = function getKey() { return this.key; } ; // {return key} is a ReferenceError!!
}
function IntervalBuilder() {
this.setPerfectFifth = function setPerfectFifth(root) {
this.fifth = new Note();
console.log("this.fifth: " + this.fifth);
this.y = root.key;
console.log("root.key: " + root.key );
console.log("y: " + this.y );
this.fifth.setKey( this.y + 4 );
return this.fifth;
};
}
With the above I can now do this:
var x = new Note();
var ib = new IntervalBuilder();
ib.setPerfectFifth(x);
However, the instance ib now has a member named fifth! What I was hoping for was that I could assign the return value (a Note) from setPerfectFifth to a variable and let fifth vanish. How is that done?
Many thanks for any help, I find lots of this very confusing.
Gerard
Since you titled your quesion variable visibility in javascript what is basically going on is: In this.fifth = new Note(); the keyword this references the instance (the ib of var ib = new ...). So you attach your newly created Note to the instance. In JavaScript, as long as a variable can be reached starting with the global Object (window, when you think of a graph), it won't get garbage-collected away.
What you want is: var fith = new Note(), which will create a local variable which will get freed as soon as the function execution ends. Clearly, every usage of this.fifth then has to be replaced by just fith.
I do not know exactly what you want to achieve, but I think you want the following code structure:
// ==============================
// NOTE "CLASS"
// ==============================
var Note = (function () {
// Constructor
function Note() {
this._key = 1 + Math.floor( Math.random() * 13);
}
// Getter
Note.prototype.getKey = function () {
return this._key;
};
// Setter
Note.prototype.setKey = function (i) {
this._key = i;
};
return Note;
})();
// ==============================
// INTERVAL BUILDER "CLASS"
// ==============================
var IntervalBuilder = (function () {
// Constructor
function IntervalBuilder() {}
// Private members
var fifth = null,
y = 0;
// Setter
IntervalBuilder.prototype.setPerfectFifth = function (root) {
fifth = new Note();
y = root.getKey();
fifth.setKey(y + 4);
return fifth;
};
return IntervalBuilder;
})();
// ==============================
// CLIENT CODE
// ==============================
var x = new Note(),
ib = new IntervalBuilder();
ib.setPerfectFifth(x);
I'm not sure if what I am trying to do is impossible or not.
Consider this function:
function p(num) {
if (!num) num = 1;
return p.bind(null, num + 1);
}
if you call p(), inside the function num = 1, if you call p()(), num = 2 and so on. But, there is no way to actually return or obtain num from p because it always returns a bound copy of itself with the number trapped in its unexecutable closure.
Anyway, I'm curious (a) if there is a way to pull the argument out of the bound function, or (b) there is another way to count in this fashion.
I have two answers depending on what you want. If you simply want something "imperative" and "stateful":
function p() {
if (!p.num) p.num = 0;
p.num = 1 + p.num;
return p;
}
p();
p.num; // 1
p();
p.num; // 2
p()();
p.num; // 4
p()()();
p.num; // 7
Or if you want it to be "stateless":
function p() {
p.num = 0;
function gen_next(prev) {
function next() {
return gen_next(next);
}
next.num = prev.num + 1;
return next;
}
return gen_next(p);
}
p().num; // 1
p()().num; // 2
p()()().num; // 3
p()().num; // still 2
p().num; // still 1
I need function change to change variables and return back to Tst1. I expect to get in console:
5
aaa
but have unchanged ones:
6
bbb
My functions:
function change ( aa,bb )
{
aa=5;
bb="aaa";
}
function Tst1()
{
aa=6;
bb="bbb";
change(aa,bb);
console.log (aa);
console.log (bb);
}
One way is to move change() into the function test(). Then it shares the same variables as the calling scope.
'use strict';
function test() {
function change() {
aa = 6;
bb = 76;
}
var aa = 5,
bb = 6;
change();
document.write(aa + " " + bb);
}
test();
JavaScript is like java in that primitives are never passed by reference but objects are always passed by reference. You need to wrap your data in an object and pass that instead:
function change (aa, bb)
{
aa.value = 5;
bb.value = "aaa";
}
function Tst1()
{
aa = { value: 6 };
bb = { value: "bbb" };
change(aa, bb);
console.log (aa.value); // outputs 5
console.log (bb.value); // outputs aaa
}
or you can play with global variable, but it is not a good practice.
var aa,bb;
function change(){
aa=6;
bb=76;
}
function test(){
aa = 5;
bb = 6;
change();
console.log(aa + " " + bb);
}
test();
Short answer: NO, you can't pass primitive parameters by reference in JS.
One alternative solution to the presented here is to return the result values as array of items:
function change ( aa,bb )
{
aa=5;
bb="aaa";
return [aa, bb];
}
function Tst1()
{
aa=6;
bb="bbb";
result = change(aa,bb);
aa = result[0];
bb = result[1];
document.writeln(aa);
document.writeln(bb);
}
Tst1();
I'm new on Javascript. I'm trying to do this exercise, but i cannot found anything to help me with that.
I created this object
var Foo = function(value) {
this.val = value;
}
And now I need sum two Foo objects with + operator.
var first = new Foo(2);
var second = new Foo(3);
var result = first + second; //should be 5
Do I have a way to overload operator + (like c++) , declare my Foo object as an Integer or something like that?
var result = first.val + second.val;
alert(result); // 5
jsfiddle: http://jsfiddle.net/czhE3/
UPD
OK, without val:
var Foo = function(value) {
this.val = value;
this.toString = function() {
return this.val;
}
}
var first = new Foo(2);
var second = new Foo(3);
var result = first + second;
alert(result); // 5
http://jsfiddle.net/czhE3/1/
As the previous people have mentioned you cannot override operators in javascript, but you could implement a valueOf which is the arithmetic version of a toString().
Add the follow code line:
Foo.prototype.valueOf = function () { return this.val; };
or
this.valueOf = function () { return this.val; };
Working fiddle http://jsfiddle.net/fJJL9/
There is no way in Javascript to overload operators as in C++. The closest thing you can make is a sum function for your objects, like
function sum ( a, b ) { return a.value + b.value; }