Javascript constructor with closure using outside variables referencing other variables - javascript

var Beer = function(){
var moreBot = 100,
lessBot = 10,
wholeCase = moreBot + lessBot;
this.count = function(){
moreBot = 22;
lessBot = 33;
console.log(moreBot); //returns 22
console.log(lessBot); //returns 33
return wholeCase; //returns 110 instead of 55??
};
};
var Alc = new Beer();
So say I have this constructor using a closure which references the outside function variables. Then why is it that when I return wholeCase after changing the variables moreBot and lessBot do I get the sum of the originally assigned values? Thank you in advance for your expertise!

wholeCase is set at construction time. Your example is not significantly different from:
var foo = 5,
bar = 6;
var sum = foo + bar; // sum is 11
foo = 100000;
console.log(sum); // sum is still 11; we never changed sum
You either need to recompute wholeCase each time you use it, or just make it a function:
var Beer = function(){
var moreBot = 100,
lessBot = 10,
computeWholeCase = function() { return moreBot + lessBot };
this.count = function(){
moreBot = 22;
lessBot = 33;
return computeWholeCase(); // run computeWholeCase to return 55
};
};

Related

JavaScript create an object outside of a constructor function and add 2 methods

I have a constructor function Example that has 2 methods.
I want to create a new object outside of the constructor function and call the 2 methods that are in it.
How do I do that, the task doesn't say anything about the rest of the content.
Something like var newEx = new Example will create an object identical to the constructor function.
Thank you
function Example (){
this.name = Mike;
this.surname = Ryan;
this.age = 50;
this.x = function(){
return 20
}
this.y = function (){
return 50
}
}
A Simple Example For You
I think it will help you to understand.
function Person(name,dob){
this.name = name;
this.birthday = new Date(dob);
this.calAge = function(){
const diff = Date.now() - this.birthday.getTime();
const ageDate = new Date(diff);
return Math.abs(ageDate.getUTCFullYear() - 1970 );
}
}
const shovon = new Person('Shovon', '8-26-1991');
console.log(shovon);
console.log(shovon.name);
console.log(shovon.calAge());
NOW, FROM YOUR CODE
function Example(){
this.name = Mike;
this.surname = Ryan;
this.age = 50;
this.x = function(){
return 20
}
this.y = function (){
return 50
}
}
const newObj = new Example(); // New Object Created
newObj.x(); // call x function , it will execute and return 20
console.log(newObj.x()); // Now it will show the result in console
//You can store the return value in a variable like this
var a = newObj.x();

variable visibility in javascript

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);

How can javascript like varName.myFunction()

function CircleArea(Value) {
var Results = 3.14 * Value^2;
return Results;
}
So I want:
var Diameter = 30;
Diameter.CircleArea(); // Results 2826
Like:
var n = 30; n.toString() // Results 30
Syntax:
varName.myFunction();
You can but rarely should extend prototypes:
Number.prototype.circleArea = function() {
var value = this;
return Math.pow(value, 2) * Math.PI;
};
var num = 30;
console.log(num.circleArea()); // 2827.4333882308138
Your function accepts an argument .
So you will need to pass in Diameter like so :
CirclArea(Diameter)
Returns 2826

How to define a javascript internal method that needs to be accessible from inside obj and out

I'm trying to fully grasp JavaScript inheritance and encapsulation. Take the following example (and here is a fiddle of it):
myPage = {
someObj: function() {
var x = 0;
//PRIVATE: increment by 10
var inc10 = function() {
x = x+10;
};
//PUBLIC: increment
this.inc = function() {
x = x+1;
};
//PUBLIC: decrement
this.dec = function() {
x = x-1;
};
//PUBLIC: output the current value of x
this.getValue = function() {
return x;
}
inc10(); //as soon as obj1 is created lets add 10
this.inc(); //as soon as obj1 is created lets add 1 more
}
};
obj1 = new myPage.someObj(); //x starts out at 11
// obj1.inc10(); won't work because it's private, excellent
obj1.dec();
obj1.inc();
alert(obj1.getValue());
My question is about the inc() method. I need it to be callable from inside and outside of the object. Is this the proper way to do that?
I need it to be callable from inside and outside of the object. Is this the proper way to do that?
Your script does seem to work as expected already, you are calling the method as this.inc() in your constructor perfectly fine - not sure why it needs improvement.
You could however define it as a local function, which you then are going to export as a method - and have it still available "inside" as a local variable:
function SomeObj() {
// local declarations:
var x;
function inc10() {
x = x+10;
}
function inc1() {
x = x+1;
}
// exported as property:
this.inc = inc1; // <== the function from above, not a literal
this.dec = function() {
x = x-1;
};
this.getValue = function() {
return x;
};
// initialisation:
x = 0;
inc10();
inc1(); // this.inc() would still work
}
To call function from inside and outside without attaching it to an obj.
This should work ...
myPage = function() {
var x = 0;
//PRIVATE: increment by 10
var inc10 = function() {
x = x+10;
};
//PUBLIC: increment
this.inc = function() {
x = x+1;
};
//PUBLIC: decrement
this.dec = function() {
x = x-1;
};
//PUBLIC: output the current value of x
this.getValue = function() {
return x;
}
inc10(); //as soon as obj1 is created lets add 10
this.inc(); //as soon as obj1 is created lets add 1 more
};
obj1 = new myPage; //x starts out at 11
// obj1.inc10(); won't work because it's private, excellent
obj1.inc();
alert(obj1.getValue());

Triggering Instance methods by firing the Parent method

What is the best way to fire a method in many children by calling the parent's method?
For example, lets say I have a parent object Foo which has many instances: BarX, BarY, etc.
Foo = function(){
x = null;
y = null;
move = function(){
x += 1;
y += 1;
};
}
BarX = new Foo();
BarX.x = 50;
BarX.y = 50;
BarY = new Foo();
BarY.x = 200;
BarY.y = 200;
Is there any easy way to fire off the move function in all instances? Am I limited to looping through the instances and firing off the function like that or can I somehow fire the function in Foo and have it trickle down and fire off all instances who extend Foo?
No. But you could be more clever about it. Make a static moveAll function on Foo. Examples make things clearer. Here is the fiddle.
var Foo = function(x, y){
this.x = x;
this.y = y;
this.move = function(){
x += 1;
y += 1;
alert(x + ' ' + ' ' + y);
};
Foo.instances.push(this); // add the instance to Foo collection on init
};
Foo.instances = [];
Foo.moveAll = function(){
for(var i = 0; i < Foo.instances.length; i++)
Foo.instances[i].move();
}
var a = new Foo(5, 6);
var b = new Foo(3, 4);
Foo.moveAll();

Categories