JS Using prototype function in prototype - javascript

Hey i'am writing a little object :
function Point(x, y) {
this.x = x;
this.y = y;
this.angle = Math.sqrt(x * x + y * y);
this.radius = Math.atan(y / x);
};
Point.prototype = {
constructor: Point,
calculateRadius: function(x, y) {
return Math.sqrt(x * x + y * y);
},
calculateAngle: function(x, y) {
return Math.atan(y / x);
},
cartToRad: function(x, y) {
this.radius = calculateRadius(x, y);
this.angle = calculateAngle(x, y);
}
};
var coords = new Point(0, 0);
coords.cartToRad(5, 0.523);
And that throw an error:
ReferenceError: calculateRadius is not defined.
Is it possible to use prototype functions in other prototype functions?

You need to reference them as properties of this, just like any other property.

Related

Calling a nested function from global scope [duplicate]

This question already has answers here:
Loop (for each) over an array in JavaScript
(40 answers)
Closed 4 years ago.
So, i have the following code:
this.balls = [];
function setup() {
createCanvas(800, 800);
noStroke();
balls.push(new Ball(width / 2, height / 2, 20))
}
function draw() {
for (var ball in this.balls) {
ball.drawCircle();
}
}
this.Ball = function(x, y, r) {
console.log("Ball created");
this.x = x;
this.y = y;
this.r = r;
this.drawCircle = function (){
ellipse(x, y, r);
}
}
The problem is that i get the following error:
Uncaught TypeError: ball.drawCircle is not a function
at draw (sketch.js:12)
at e.d.redraw (p5.min.js:6)
at e.<anonymous> (p5.min.js:4)
at e.<anonymous> (p5.min.js:4)
at new e (p5.min.js:5)
at e (p5.min.js:4)
So it should call the drawcircle funtion for every ball in the balls array, however it says that drawCircle is not a function. The problem is that I just don't understand why. I have tried using var drawCircle instead of this.drawCirle, I also tried using funcion drawCircle.
Kind regards.
p.s. this code uses p5.js, the Ball created log is executed
Try using a class so you don't have issues with this context:
function Ball(x, y, r) {
console.log("Ball created");
this.x = x;
this.y = y;
this.r = r;
}
Ball.prototype.drawCircle = function() {
ellipse(x, y, r);
};
Or in ES6:
class Ball {
constructor(x, y, r) {
console.log("Ball created");
this.x = x;
this.y = y;
this.r = r;
}
drawCircle() {
ellipse(x, y, r);
}
}

JS object inheritance with attributes

Im trying to get a very simple inheritance pattern for my Project going, extending from a base class into a specialized class. However, my specialized class's attributes are being overwritten by the parent's attributes.
Why is that and how can i fix it ?
thanks,
function Ship(className, x, y){
this.className = className;
this.x = x;
this.y = y;
this.speed = 0;
}
function Corvette(className, x, y){
this.className = className;
this.x = x;
this.y = y;
this.speed = 100;
Ship.call(this, className, x, y)
}
Corvette.prototype = Object.create(Ship.prototype);
var ship = new Ship("Biggie", 50, 50);
var corvette = new Corvette("Smallish", 50, 50);
console.log(Corvette.className) // "Smallish" - correct via parameter.
console.log(Corvette.speed) // should be 100, is 0 - not correct, "static" from parent attribute
console.log(Corvette.constructor.name) // Ship
Why you have the same properties in the child object which are already in the parent's?
I suggest you to do
function Ship(className, x, y, speed = 0) {
this.className = className;
this.x = x;
this.y = y;
this.speed = speed;
}
function Corvette(className, x, y, speed = 100) {
Ship.call(this, className, x, y, speed);
}
Corvette.prototype = Object.create(Ship.prototype);
Corvette.prototype.constructor = Corvette;
var ship = new Ship("Biggie", 50, 50);
var corvette = new Corvette("Smallish", 50, 50);
console.log(corvette.className) // "Smallish" - correct via parameter.
console.log(corvette.speed) // should be 100, is 0 - not correct, "static" from parent attribute
console.log(corvette.constructor.name) // Ship
and if your browser supports some features of ES6 use this feature ES6 classes.
class Ship { // And also Ship is an abstractionm so you can use `abstract` keyword with it
constructor(className, x, y, speed = 0) {
this.className = className;
this.x = x;
this.y = y;
this.speed = speed;
}
}
class Corvette extends Ship {
constructor(className, x, y, speed = 100) {
super(className, x, y, speed);
}
}
var ship = new Ship("Biggie", 50, 50);
var corvette = new Corvette("Smallish", 50, 50);
console.log(corvette.className) // "Smallish" - correct via parameter.
console.log(corvette.speed) // should be 100, is 0 - not correct, "static" from parent attribute
console.log(corvette.constructor.name) // Ship
You only need to move Ship.call(this, className, x, y) at the start of Corvette function.
Also, next time, before posting code, check it is correct, you wrote console.log(Corvette) instead of console.log(corvette)
Another thing: you do not need to repeat params you do not want to overwrite
function Ship(className, x, y){
this.className = className;
this.x = x;
this.y = y;
this.speed = 0;
}
function Corvette(className, x, y){
Ship.call(this, className, x, y)
this.speed = 100;
}
Corvette.prototype = Object.create(Ship.prototype);
var ship = new Ship("Biggie", 50, 50);
var corvette = new Corvette("Smallish", 50, 50);
console.log(corvette.className)
console.log(corvette.speed)
console.log(corvette.constructor.name)
You should invoke the parentclass contructor first and then override the properties, this way the properties set by Corvette will not be changed by the parent class i.e.:
function Corvette(className, x, y){
Ship.call(this, className, x, y)
this.speed = 100;
}

javascript base object to create 2 other objects with different methods

I've been playing around with javascript for years, but I'm trying to get serious now. Studying, and into Objects.
I want to create a base object, and use it to create 2 other objects that are slightly different.
I thought this would work :
function movingObject(x, y, z){
this.x = x;
this.y = y;
this.z = z;
}
var positiveMover = new movingObject(x, y, z);
positiveMover.prototype.move = function(a, b){
yadda yadda
}
var negativeMover = new movingObject(x, y, z);
negativeMover.prototype.move = function(b, a){
adday adday
}
var pic = postiveMover(1, 2, 3);
pic.move(20, 10);
I get a undefined error on the move.....pretty sure I've got the wrong idea. Any advice would be appreciated - links to information, or the right keywords to google
I think it is more like two classes, that you want to build :
function movingObject(x, y, z){
this.x = x; this.y = y; this.z = z;
}
// positive mover : child class of movingObject
function positiveMover (x, y, z) {
// use parent class's constructor.
movingObject.apply(this,arguments);
};
// inherit parent's class.
positiveMover.prototype = Object.create(movingObject.prototype);
positiveMover.prototype.move = function(a, b){ yadda yadda }
However, if you seek a per-instance choice of a method, you could do :
function movingObject(x, y, z, movingMethod){
this.x = x; this.y = y; this.z = z;
this.move = movingMethod;
}
Or just set the move property of a moving object, thus overriding the default prototype :
function movingObject(x, y, z){
this.x = x; this.y = y; this.z = z;
}
movingObject.prototype.move= function(a,b) { /*some default code*/}
var oneMover = new movingObject(0,0,0);
oneMover.move = function(a,b) { /* some specific code */ };

How to instantiate a class(ClassA) inside another class(ClassB) and use the ClassA object as a property in ClassB in JavaScript?

Consider the following code:
function Coord(x, y) {
this.x = x;
this.y = y;
}
function Ellipse() {
this.Text = Text;
this.Cx = Cx;
this.Cy = Cy;
this.Rx = Rx;
this.Ry = Ry;
}
Now in the function Ellipseinstead of using Cx, Cy etc. I want to instantiate the function Coord for each pair to achieve something as follows:
function Coord(x, y) {
this.x = x;
this.y = y;
}
function Ellipse() {
this.Text = Text;
Coord C = new C(); // where C has its own properties x and y
Coord R = new R(); // where R has its own properties x and y
}
Try this:
function Coord(x, y) {
this.x = x;
this.y = y;
}
function Ellipse(text, cx, cy, rx, ry) {
this.text = text;
var c = new Coord(cx, cy);
var r = new Coord(rx, ry);
}
I don't know how you thought of Coord C = new C() but it's absolutely wrong. JavaScript variables have no types.
Also from where are you getting Text, Cx, Cy, etc? Shouldn't they be passed as arguments to the constructor?

Why is object property changed for all instances?

I wanted to encapsulate the position of a sprite within another object. So that instead of using tile.x and tile.y I would access via tile.position.x and tile.position.y.
Yet once I set the value of tile.position within the init-method all the instances of the tile-object change to the same value. Why is that?
As when I set tile.x everything works as expected, meaning each object gets the right value.
This is how I create the multiple instances:
In a for loop I am creating multiple instances of said object:
for (var y = 0; y < 10; ++y) {
for (var x = 0; x < 10; ++x) {
var tile = Object.create(tileProperty);
tile.init(x, y);
...
}
}
And this is the cloned object:
var tileProperty = {
// this works
x: null,
y: null,
// this will get changed for ALL instances
position: {
x: null,
y: null
},
init: function(x, y) {
this.name = x.toString() + y.toString();
this.x = x;
this.y = y;
this.position.x = x;
this.position.y = y;
this.canvas = document.createElement('canvas');
var that = this;
$(this.canvas).bind('click', function() {
console.log(that.position, that.x, that.y);
});
document.body.appendChild(this.canvas);
}
}
Use this:
var tileProperty = {
position: { // we will inherit from this
x: null,
y: null,
init: function(x, y) {
this.x = x;
this.y = y;
}
},
init: function(x, y) {
this.name = x.toString() + y.toString();
// create an own Position object for each instance
this.position = Object.create(this.position);
// and initialize it
this.position.init(x, y); // you might inline this invocation of course
…
},
…
}
You're having a reference to the same position object in all your objects.
What you should do is using the standard prototype solution :
function tileProperty() {
this.position = {
x: null,
y: null
};
}
tileProperty.prototype.init = function(x, y) {
this.name = x.toString() + y.toString();
this.x = x;
this.y = y;
this.position.x = x;
this.position.y = y;
this.canvas = document.createElement('canvas');
var that = this;
$(this.canvas).bind('click', function() {
console.log(that.position, that.x, that.y);
});
document.body.appendChild(this.canvas);
}
and then build your instance using
var tp = new tileProperty();

Categories

Resources