passing parent object automatically - javascript

So I have a couple of classes
function BaseClass(x, y){
this.x = x;
this.y = y;
}
function ImageClass(img, w, h, x, y){
BaseClass.call(this, x, y);
this.img = img;
}
ImageClass.prototype = Object.create(BaseClass.protoype);
ImageClass.prototype.constructor = ImageClass;
function LayerClass(img, w, h, x, y){
ImageClass.call(img, w, h, x, y);
this.collection = [];
this.createSprite = function(img, r, a, w, h, x, y){
this.collection.push(new Sprite(img, r, a, w, h, x, y));
}
}
LayerClass.prototype = Object.create(ImageClass.prototype);
LayerClass.prototype.constructor = LayerClass;
function SpriteClass(img, r, a, w, h, x, y){
ImageClass.call(img, w, h, x, y);
this.r = r;
this.a = a;
}
SpriteClass.prototype = Object.create(ImageClass.prototype);
SpriteClass.prototype.constructor = SpriteClass;
In my code each of the inherited classes uses call() to pass 'this'
The problem being is that if I have a Layer object that contains any Sprite objects, I would like the Sprite objects to have a parent (super) reference and I can't do this because the class constructors use this to set properties.
So does anyone know how I could pass the parent or (and I know this is going to sound dumb, it's late) be able to get the parent scope this in the class constructor?
While writing this I realized that it might be as simple as setting the parent property after the object is set as a child but I'm looking for confirmation if that's the best way or if anyone knows something better. Also feel free to tell me I know nothing about prototype because I'm still learning it. :-)
-Thanks

Would this work? Its not automatic, but still works. Javascript does not have native support for classes, so it has its limitations.
function LayerClass(img, w, h, x, y){
ImageClass.call(img, w, h, x, y);
this.collection = [];
this.createSprite = function(img, r, a, w, h, x, y){
var spriteObj = new Sprite(img, r, a, w, h, x, y);
spriteObj.parent = this;
this.collection.push(spriteObj);
}
}
You will be able to access the parent variable of spriteObject.
Also, if you are looking for inheritance, try coffee script. It compiles back to javascript and handles most of the inheritance problems for you.

Related

shorthand way to reference `this` propeties?

I have a class
class Foo {
constructor(x, y) {
this.x = x
this.y = y
Bar() {
console.log(this.x, this.y)
}
I recall seeing a method of referring to this. variables without having to specify this. Something like
class Foo {
constructor(x,y) {
this.x = x
this.y = y
Bar() {
x,y = [this] // something like this
console.log(x, y) // equivalent to this.x, this.y
}
I desire this because I have dozens of statements that call methods on this.ctx - like this.ctx.rect() - and I don't want to have to have this. prepended to all of them for the sake of readability.
Is there a syntax for this?
You can deconstruct this like any JavaScript object,
Bar() {
const {x, y} = this;
}
I do not recommend doing this however, it seems like it would not scale well as a technique.
Objects (including arrays and functions) are handled by reference, meaning that if you write
let a = this.ctx;
then a points to the same object as ctx and you can do a.rect().

In JavaScript, is there a way to write global functions in a static style? (I'm not sure that I worded that correctly)

I know that you can write functions which work if you input different arguments. However, is there a way to add a function which you can write such as
vector.function(arguments);.
When I write the functions, I use the vector or object as an argument to get the value back, but is there a way to write it like I have above?
var Vector = function(x, y) {
this.x = x;
this.y = y;
}
Vector.prototype.yourFunction = function() {
/* access vector properties */
console.log(this.x, this.y);
}
var vector = new Vector(1,2);
vector.yourFunction(); // 1 2
It looks like what you want it an object containing a set of functions inside of it. When functions are defined inside of an objects, these are commonly referred to as "methods". This is a useful way of "namespacing" a set of common methods. You can achieve this in many ways. Here is the most basic way:
const vector = {
x: 0,
y: 0,
getDirection() {
return Math.atan2(this.y, this.x);
},
};
console.log(vector.getDirection());
This will work fine if you only need one vector. If you want to have many vectors, you can use instantiation to create as many vectors as you need. For example:
// Globally defined function
function getDirection(x, y) {
return Math.atan2(y, x);
}
function Vector(x = 0, y = 0) {
this.x = x;
this.y = y;
this.getDirection = () => {
// Defer to the globally defined function
return getDirection(x, y);
};
return this;
}
const vectors = [new Vector(10, 15), new Vector(0, 10), new Vector(10, 50)];
vectors.forEach((vector) => {
console.log(vector.getDirection());
});

creating many similar elements in javascript animation

For a javascript animation, I am trying to create buttons with the numbers 1-9 on them. Right now my javascript for the number 1 looks like:
that1 = { thisx : 120, thisy: H-400, thisnumber= "1",
draw: function() {
var keywidth = 100;
var keyheight = 150 ;
var x = this.thisx;
var y = this.thisy;
var cornercut = 5;
ctx.beginPath();
//drawing the key
ctx.moveTo(x, y+cornercut);
ctx.quadraticCurveTo(x,y, x+cornercut, y);
ctx.lineTo(x+keywidth-cornercut, y);
ctx.quadraticCurveTo(x+keywidth, y, x+keywidth, y+cornercut);
ctx.lineTo(x+keywidth, y+keyheight-cornercut);
ctx.quadraticCurveTo(x+keywidth, y+keyheight, x+keywidth-cornercut, y+keyheight);
ctx.lineTo(x+cornercut, y+keyheight);
ctx.quadraticCurveTo(x, y+keyheight, x, y+keyheight-cornercut);
ctx.lineTo(x, y+cornercut);
ctx.closePath();
ctx.stroke();
ctx.fillText(this.thisnumber, x+.5*keywidth,y+.8*keyheight);
},
highlight: function() {
ctx.fillStyle="red";
ctx.fill();
}
} ;
I could just copy this to create this2, this3, this4, this5, etc., but I feel like there is an easier way. Can anyone help? I am using JS because I believe it will be the easiest way to control these objects using animation, but please let me know if you have another suggestion.
You could change the values of thisx and thisy and simply call the draw function again, but the code would probably be more elegant if you simply passed in the values as arguments to a draw function.

Javascript simulating classes

I'm trying to simulate a class in javascript. I'm new to it (and also to stackoverflow)
and want to learn. Somebody who gives me java explained it like this, but it doesn't work. What am I doing wrong?
function rectangle (width,height,x,y,jumping)
{
return { x: x,
y: y,
width: width,
height: height,
jumping: jumping};
}
var ava = new rectangle (5,5,10,20,10);
alert (x.ava) ;
Help appreciated
Thanks in advance (I hope I post this right)
edit: Thank you Philipp :)
Try this.
// this is how you write a class
function Rectangle(width, hight, x, y, jumping) {
this.x = x;
this.y = x;
this.width = width;
this.height = height;
this.jumping = jumping;
}
var ava = new Rectangle(5, 5, 10, 20, 10);
alert(ava.x);
also your variable is ava and calls x you had it backwards x.ava.
well your variable is not "x"
var ava = new rectangle (5,5,10,20,10);
alert (x.ava); You are looking for a variable x with a property of ava
When you run your code you get the error:
Uncaught ReferenceError: x is not defined
You want to use your variable that has the properties. You should have written it as:
alert (ava.x);

Invoke "superclass" constructor in JavaScript

I just got into JavaScript and I'm kind of puzzled by its object-oriented behavior.
I was just trying to create a class Point2D with x,y members and extend it with a Point3D class with x,y,z members.
The behavior I'm trying to achieve is something like, let's say it in C#:
class Point2D
{
int x, y;
public Point2D(int x, int y) { this.x = x; this.y = y; }
}
class Point3D : Point2D
{
int z;
public Point3D(int x, int y, int z) : base(x, y) { this.z = z; }
}
I read a lot of stuff but I don't seem to really find what I'm looking for.
Here's what I've come up to so far:
function Point2D(x, y) { this.x = x; this.y = y; }
Point2D.prototype.constructor = Point2D;
function Point3D(x, y, z) { Point2D.prototype.constructor.call(this); this.z = z; }
Point3D.prototype = new A(); // see latter explanation
Point3D.prototype.constructor = B;
var p = new Point3D(10, 20, 30);
Which is obviously wrong.
Now, I know I should do something like Point3D.prototype = new A(x, y) but I don't want to create a prototype with fixed x,y coordinates and variable z.
It must be very simple, but I'm just not getting it, I can't seem to call the superclass constructor or to make it behave properly.
JavaScript's prototypal inheritance provides a couple of different flexible ways to perform the kind of polymorphic constructors you're looking for. In your particular example, you want something like this:
function Point2D(x, y) {
this.x = x;
this.y = y;
}
function Point3D(x, y, z) {
Point2D.call(this, x, y);
this.z = z;
}
Fussing with explicitly setting the constructor on the prototype is not strictly necessary here. (It is really only necessary when you are creating the prototype "all at once" -- e.g., with an object.)
For a detailed discussion of object-oriented JavaScript, I'd recommend Nicholas Zakas' Principles of Object-Oriented Programming in JavaScript (ebook) or the discussion of prototypes and inheritance in his other book, Professional JavaScript for Web Developers.

Categories

Resources