How to extend a class inside a namespace in javascript? - javascript

var sl = sl || {}
sl.Shape = function(){
this.x = 0;
this.y = 0;
};
sl.Shape.prototype.move = function(x,y){
this.x += x;
this.y += y;
};
sl.Rectangle = function(){
sl.Shape.call(this);
this.z = 0;
};
The next line produces the error (Object prototype undefined, has to be Object or null). As far as I can see this is because Shape is "namespaced".
sl.Rectangle.protoype = Object.create(sl.Shape.protoype);
sl.Rectangle.protoype.constructor = sl.Rectangle;
How do I do this correctly?

You should use word prototype instead protoype.

You have misspelled the word "prototype" as Andrii pointed out, try this example:
(function() {
var sl = sl || {};
function Shape() {
this.x = 0;
this.y = 0;
}
Shape.prototype.move = function(x, y) {
this.x += x;
this.y += y;
};
function Rectangle() {
Shape.apply(this, arguments);
this.z = 0;
};
Rectangle.prototype = Object.create(Shape.prototype);
Rectangle.prototype.constructor = Rectangle;
sl.Shape = Shape;
sl.Rectangle = Rectangle;
// expose
window.sl = sl;
}());
Usage
var shape = new sl.Shape();
var rect = new sl.Rectangle();

Related

Why the code is giving me error "SyntaxError: Unexpected token {"?

While executing the below code, getting Error : SyntaxError: Unexpected token {
const a = function(x,y){
this.x = x;
this.y = y;
getX(){
return this.x;
}
getY(){
return this.y;
}
};
const newA = new a( '1', '2' );
console.log( newA.getX() );
console.log( newA.getY() );
Expected Result : 1 2
What you wrote is valid for ES6+ class declaration:
class a {
constructor(x, y) {
this.x = x;
this.y = y;
}
getX() {
return this.x;
}
getY() {
return this.y;
}
};
const newA = new a('1', '2');
console.log(newA.getX());
console.log(newA.getY());
If you are using a normal function, then you need to assign the properties explicitly:
const a = function(x, y) {
this.x = x;
this.y = y;
this.getX = function() {
return this.x;
}
this.getY = function() {
return this.y;
}
};
const newA = new a('1', '2');
console.log(newA.getX());
console.log(newA.getY());
Or use a prototype, so every instance of a will use the same methods, instead of making one set per instance:
const a = function(x, y) {
this.x = x;
this.y = y;
};
a.prototype.getX = function() {
return this.x;
}
a.prototype.getY = function() {
return this.y;
}
const newA = new a('1', '2');
console.log(newA.getX());
console.log(newA.getY());
The functions need to be assigned as properties, ref:
const a = function(x, y) {
this.x = x;
this.y = y;
this.getX = function() {
return this.x;
}
this.getY = function() {
return this.y;
}
};
const newA = new a('1', '2');
console.log(newA.getX());
console.log(newA.getY());
That's not how classes work in javascript. There are two ways to do OO in javascript:
Traditional, prototype-based OO:
// Traditionally javascript does not have classes, but functions can
// behave as constructors if you give it a prototype:
function A (x, y) {
this.x = x;
this.y = y;
}
A.prototype.getX = function() {return this.x};
A.prototype.getY = function() {return this.y};
Alternatively you can use the new class syntax:
"New" ES6 classes (actually it's quite old now)
class A {
constructor (x,y) {
this.x = x;
this.y = y;
}
getX() { return this.x }
getY() { return this.y }
}
You are mixing elements of both syntax - which unfortunately results in invalid syntax
You are using class syntax inside a function.
You can create a constructor function and add the methods to a.prototype
function a(x, y) {
this.x = x;
this.y = y;
};
a.prototype.getX = function() {
return this.x;
}
a.prototype.getY = function() {
return this.y;
}
const newA = new a('1', '2');
console.log(newA.getX());
console.log(newA.getY());
Or, create a class like this:
class a {
constructor(x, y) {
this.x = x;
this.y = y;
}
getX() {
return this.x;
}
getY() {
return this.y;
}
};
const newA = new a('1', '2');
console.log(newA.getX());
console.log(newA.getY());
Another option is to create a getter for X an Y:
class a {
constructor(x, y) {
this.x = x;
this.y = y;
}
get X() {
return this.x;
}
get Y() {
return this.y;
}
};
const newA = new a('1', '2');
console.log(newA.X);
console.log(newA.Y);
The syntax:
getX(){
return this.x;
}
… is for use inside an object literal or a class, not a function expression.
class A {
constructor(x, y) {
this.x = x;
this.y = y;
}
getX() {
return this.x;
}
getY() {
return this.y;
}
};
const newA = new A('1', '2');
console.log(newA.getX());
console.log(newA.getY());

How to reset the variables of an object?

I am trying to reset the following objects inside a
draw = function() {...}
var Beaver = function(x, y) {
this.x = x;
this.y = y;
this.img = getImage("");
this.sticks = 0;
this.holes = 0;
this.npcs = 0;
};
var Stick = function(x, y) {
this.x = x;
this.y = y;
};
var Hole = function(x, y) {
this.x = x;
this.y = y;
};
var Npc = function(x, y) {
this.x = x;
this.y = y;
this.img = getImage("");
};
How to do that?

Declare method outside of class

i know i can add a method by doing:
point.prototype.move = function ()
{
this.x += 1;
}
But, is there a way to add a method to a class by assigning a function that is declared outside of it to one of its propertie?
I am pretty sure this can't work but it gives an idea about what i'am trying to do:
function point(x, y)
{
this.x = x;
this.y = y;
this.move = move();
}
function move()
{
this.x += 1;
}
The only reason your example doesn't work is because you are calling move() and assigning its result which is undefined.
You should just use a reference to the move function when assigning it.
function move()
{
this.x += 1;
}
function point(x, y)
{
this.x = x;
this.y = y;
this.move = move
}
Different ways to do it
// Attach the method to the prototype
// point.prototype.move = move;
// Attach the method to the instance itself
// var myPoint = new point(1,2); myPoint.move = move;
function point(x, y, move)
{
this.x = x;
this.y = y;
this.move = move;
}
function move()
{
this.x += 1;
}
var obj = new point(2, 5, move);

Why var a is undefined? Javascript OOP

I have this code. It creates an object with x and y field. I want to add a method, which creates new object with additional width and height fields. But despite my tryings it keeps returning undefined. What is wrong?
JSFiddle
function $ (x, y) {
this.x = x;
this.y = y;
return this;
}
$.prototype.$ = function (x, y) {
this.width = x - this.x;
this.height = y - this.y;
return this;
}
var a = $(10,10).$(30,30);
alert(a.width);
var a = (new $(10,10)).$(30,30); //You need new
alert(a.width);
Also it might not be a good idea to have an instance function of a class to have the same name as the class -- it is a little confusing.
Here is how you can do what you want to do with 2 "Point" objects (as asked for in the comments):
var Point = (function(){
var Point = function(x, y) {
this.width = x;
this.height = y;
}
Point.prototype.removePoint = function(point) {
return new Point(point.width - this.width, point.height - this.height);
}
return Point;
})()
var a = new Point(10,10);
var b = new Point(30,30);
var c = a.removePoint(b);
alert(c.width);
Fiddle: http://jsfiddle.net/maniator/d3fx7/
You missed the new before $; This works:
var a = new $(10,10).$(30,30);

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