I'm incredibly new to javascript and the way classes and methods work are confusing me.
Basically I have code like this:
function container(x, y, z) {
this.x = x;
this.y = y;
this.z = z;
this.sumUp = function addUp(x, y, z) {
var a = x + y + z;
};
}
What I want to do is elsewhere in my code use the function defined within the container, using the values in container. How do I actually go about doing this?
Something along the lines of
container1 = new container (1, 2, 3);
container.sumUp(this.x, this.y, this.z);
Or something like that. I'm very confused and thinking I'm going about the whole thing wrong.
I think you want somwthing like this:
function Container(x, y, z){
this.x = x;
this.y = y;
this.z = z;
this.sumUp = function addUp(x, y, z){
alert(this.x + this.y + this.z);
};
}
container_instance = new Container(1, 2, 3);
container_instance.sumUp();
But I recomend:
function Container(x, y, z){
this.x = x;
this.y = y;
this.z = z;
}
Container.prototype.sumUp = function addUp(x, y, z){
alert(this.x + this.y + this.z);
};
container_instance = new Container(1, 2, 3);
container_instance.sumUp();
That is how it works (short):
In JavaScript you have objects, they are like hashes:
var obj = {
'a': 1,
'b': 2,
'c': 3
};
And you can get or set values by keys:
alert(obj.a); // alerts 1
alert(obj['a']); // same thing
obj['c'] = 4;
In your case Container is function which will build your object. When you do new Container(1, 2, 3); it creates an empty object, and execute the function in the context of the object.
function Container(x, y, z){
this.x = x;
this.y = y;
this.z = z;
}
// There is no point to put parameters there since they are already instance variables.
Container.prototype.sumUp = function addUp(){
alert(this.x + this.y + this.z);
};
container_instance = new Container();
container_instance.sumUp();
Related
I am trying to call a function does multiplication On another function that accepts two numbers as parameters. i Have tried using constructor and nested function, but to no avail. i have tried the followings:
function Coordinate(a, b) {
var x, y;
return {x: a, y: b};
function multiply(n) {
x * n;
y * n;
}
}
var makeCoordinate = new Coordinate(2,3);
console.log(makeCoordinate.multiple(2));
// expected output: 4 6;
You should set multiply to be on the Coordinate's prototype so that when you call new Coordinate, the instantiated object will have multiply as a method. For it to work, you should also set this.x and this.y instead of returning an object directly:
function Coordinate(a, b) {
this.x = a;
this.y = b;
}
Coordinate.prototype.multiply = function(n) {
this.x *= n;
this.y *= n;
return this;
}
var makeCoordinate = new Coordinate(2,3);
console.log(makeCoordinate.multiply(2));
Or, if you wanted multiply to return just the multiplied coordinates without changing the original object, then return the coordinates alone:
function Coordinate(a, b) {
this.x = a;
this.y = b;
}
Coordinate.prototype.multiply = function(n) {
return [this.x * n, this.y * n];
}
var makeCoordinate = new Coordinate(2,3);
console.log(makeCoordinate.multiply(2));
The answer modified two parts:
the creation of Coordinate members
multiple -> multiply
Hope this help :)
function Coordinate(a, b) {
this.x = a;
this.y = b;
this.multiply = function(n) {
return this.x * n + " " + this.y * n;
}
}
var makeCoordinate = new Coordinate(2,3);
console.log(makeCoordinate.multiply(2));
Well, firstly your console.log is calling multiple, not multiply.
Second, try an approach like this:
function Coordinate( a, b )
{
function multiply( n )
{
this.x = this.x * n;
this.y = this.y * n;
return this;
}
var co = { x: a, y : b };
co.multiply = multiply.bind( co );
return co;
}
Having clarified in the comments, the (simplest)solution is:
// important code
function Coordinate(a,b) {
this.x = a;
this.y = b;
this.multiply = function (n) {
this.x = this.x*n;
this.y = this.y*n;
}
}
// test code
let coord = new Coordinate(2,3);
console.log("Original Coordinate:");
console.log(coord);
coord.multiply(2);
console.log("Changed Coordinate: ");
console.log(coord);
You could also put the function in the prototype if you don't want a copy of it in every Coordinate object.
I am trying to take a new Point object as the argument of the plus method and then add to return the value. Point p will be correct in java but not in javascript.
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
plus(Point p) {
console.log(p.a);
return new Point(p.a + this.x, p.b + this.y);
}
}
console.log(new Point(1, 2).plus(new Point(2, 1)));
// → Point{x: 3, y: 3}
You need to take the right properties and arguments without type.
class Point {
constructor (x, y) {
this.x = x;
this.y = y;
}
plus (p) {
return new Point(p.x + this.x, p.y + this.y);
}
}
console.log(new Point(1, 2).plus(new Point(2, 1)));
I have written a code with constructer Vector(it has two parameters) and I wish to pass different set of parameters through a prototype function and want to sum up the values for both set of parameters.
But I am facing a issue with printing final Vector.
function Vector(x, y) {
this.x = x;
this.y = y;
console.log(x, y);//initially this prints (3,3)
return (x, y);
}
Vector.prototype.plus = function (a, b) {
this.x = this.x + a;
this.y = this.y + b;
console.log(this.x, this.y);// After passing (1,9) it prints (4,12)but
return (this.x, this.y); //after returning (this.x, this.y) it
//prints only Y coordinate as 12
}
var type_vector = new Vector(3, 3);
console.log(type_vector.plus(1, 9));
Output: (3,3),(4,12),12
I believe you're from a python background, for there (x, y) is returned as a tuple. In JS if you return (x, y); it will be the value at the closing parenthesis (y, in this case). You must use an object or an array for your objective.
try this on console:
var a = (3, 4, 5, 6);
console.log(a);
Well, in JavaScript if you want to return an array you can use the [] notation.
Diff. this with you version :
function Vector(x, y) {
this.x = x;
this.y = y;
console.log(x, y);
return this;
}
Vector.prototype.plus = function(a, b) {
this.x = this.x + a;
this.y = this.y + b;
console.log(this.x, this.y);
return [this.x, this.y];
};
var type_vector = new Vector(3, 3);
console.log(type_vector.plus(1, 9));
Let's say I have two classes, one called Rectangle and one called Circle. Both classes have the values X and Y, is there a way to define the variables and functions once for both of the classes? Read the code below if it explains it better:
function Rectangle(msg, font){
this.msg = msg;
this.font = font;
}
function Circle(radius){
this.radius = radius;
}
Rectangle && Circle {
/* had no idea how to write the line above,
but basically for both the rectangle and the circle,
there is this code so I don't have to rewrite it for both.*/
this.position = function(x, y){
this.x = x;
this.y = y;
}
}
Yes, there is:
//creating class shape
function Shape(x,y){
this.x = x;
this.y = y;
};
//set position function
Shape.prototype.position = function(x,y){
this.x = x;
this.y = y;
};
function Rectangle(msg,font,x,y){
//calling object Shape
Shape.call(this,x,y);
this.msg = msg;
this.font = font;
}
//inheriting object Shape
Rectangle.prototype=Object.create(Shape.prototype);
function Circle(radius,x,y){
//calling object Shape
Shape.call(this,x,y);
this.radius = radius;
}
//inheriting object Shape
Circle.prototype=Object.create(Shape.prototype);
You can now call any function defined in Shape from a Rectangle or Circle object. Hope this helps.
I wrote aproximatley this code today:
function Point () { // 1
var x, y; // 2
// 3
this.setXY = function (x, y) { // 4
x = x; // 5 doesn't work
y = y; // 6 doesn't work
} // 7
} // 8
I want to make setXY API look nice so I want to use x and y on line 4. However I also want to have my code internally nice, so I use x and y on line 2 for private variables.
Question I have is: Is is possible to have x and y everywhere in my code, both for private variables and function arguments? How would I assign x to x and y to y on line 5 and 6 so that it works?
Within setXY, the function arguments x and y are shadowing the local variables x and y defined in the body of the Point function.
In javascript, there's no direct way to access a shadowed variable. By declaring your argument names to shadow the local variables, you've made the local variables inaccessible.
Commonly, instead of trying to access shadowed variables, javascript devs do one of two things in this situation:
Use a different variable name:
function Point() {
var _x, _y;
this.setXY = function(newX, newY) {
_x = newX;
_y = newY;
};
}
p = new Point();
p.setXY( 5, 7 );
Store object-specific values in this rather than as local variables:
function Point() {
this.setXY = function(x, y) {
this.x = x;
this.y = y;
};
}
p = new Point();
p.setXY( 5, 7 );
The main difference between these two approaches is that
Since they are local variables, _x and _y are inaccessible from outside of the definition of Point, so they can't be updated except via setXY.
Since they are object members, this.x and this.y are accessible to anyone who has a reference to this, and can be modified outside of the definition of Point without using setXY. To continue the prior code:
console.log( p.x, p.y ); // prints 5, 7
p.x = 11;
console.log( p.x, p.y ); // prints 11, 7
Short answer: no, it's not possible. By keeping the same names in your this.setXY method you are effectively overriding the parent scope's variables.
You seem to be allowing the raw x & y values to be modified - why not simply expose them and use your methods as utilities?
function Point (x, y) {
this.x = x;
this.y = y;
// set X,Y in a single statement
this.setXY = function (x, y) {
this.x = x;
this.y = y;
}
// utility example
this.distance = function (x, y) {
x = this.x - x;
y = this.y - y;
return Math.sqrt(x * x + y * y);
}
}
Alternatively define an object to store your variables with the same name/key:
function Point (x, y) {
// a private key store
var point = {
x: x || 0,
y: y || 0
};
this.setXY = function (x, y) {
point.x = x;
point.y = y;
}
}