I've searched for a question like mine, but it hasn't been very helpful because everyone seems to be asking (and answering) something a bit more advanced than my query (I'm at the very bottom level of JavaScript knowledge/skills).
Here is my code:
function xyPoint(x, y){
this.x = x;
this.y = y;
this.debugMessage = function(){
document.getElementById("messageArea").innerHTML =
"xyPoint(x, y) constructor called";
};
}
I want my informative message to print automatically when I do
var myPoint = new xyPoint(10, 20);
I don't want to have to execute two statements like this:
var myPoint = new xyPoint(10, 20);
myPoint.debugMessage();
Any help appreciated. Thanks.
Just call debugMessage in the constructor:
function xyPoint(x, y){
this.x = x;
this.y = y;
this.debugMessage = function(){
document.getElementById("messageArea").innerHTML =
"xyPoint(x, y) constructor called";
};
this.debugMessage();
}
You can do it as: var myPoint = new xyPoint(10, 20).debugMessage();
JSFiddle
Related
So using the following part of my code, I've been trying to find the object's name ("object's name" refers to foo, bar, baz, and jar below. Sorry if that's the improper term, couldn't find any examples like this one on the web that termed them) using the values of the constructed function. To give an example:
function myFunction(){
foo = new component(50, 50, "first", "red");
bar = new component(50, 100, "sec", "red");
baz = new component(0, 50, "third", "blue");
jar = new component(0, 100, "fourth", "blue");
}
function component(x, y, id, color){
this.x = x;
this.y = y;
this.id = id;
this.color = color;
}
So if I have the value of both x and y, 50 and 100 respectively, what method would I use to make it so that the program will recognize that the constructor with these values is bar? If doing this using two values is impossible, using only one value is totally fine since I can always just combine the two into one. So far the best thing I've been able to come up with that somehwhat worked was that "foo instanceof component" is true, so maybe there's some method that I've yet to find that's basically the opposite of instance of? Thank you in advance.
In your code foo, bar, baz and jar are variables, not constructors. These variables are pointing to objects that were created using the component function as the constructor.
It sounds like what you're trying to do is to find the object that was created using the specific values for x and y. One way to do that would be to have a lookup table where the keys are the combination of x and y, and the values are the objects:
var objects = {};
function component(x, y, id, color) {
this.x = x;
this.y = y;
this.id = id;
this.color = color;
// Insert the current object into the lookup table
objects[x + '_' + y] = this;
}
// Retreive an object from the lookup table
function findObject(x, y) {
return objects[x + '_' + y];
}
One problem with this approach is that if you create two objects with the same x and y values, only the last one will be stored in the lookup table. You could solve that by storing an array of objects for each key instead.
Using Nico's code along with Jaromanda X's self-containing code, I was able to update objects to allow the user to find the key (or is it variable, I'm still a bit unsure, whatever "foo" is) based on the new x and y values. Using
function myFunction(){
foo = new component(50, 50, "first", "red");
bar = new component(50, 100, "sec", "red");
baz = new component(0, 50, "third", "blue");
jar = new component(0, 100, "fourth", "blue");
}
var component=(function(){
var component=function(x, y, id, color){
this.x = x;
this.y = y;
this.id = id;
this.color = color;
objects[x+'_'+y] = this;
this.newPos = function(x, y){
this.x = x;
this.y = y;
//objects[this.x+"_"+this.y] = this;
};
};
component.get = function(x, y){
return objects[x+'_'+y];
};
return component
})();
'this.newPos' will change this' x and y, depending what its parameters are, but this alone will force the user to continue to use the key/variable's original x and y values, as RobG pointed out. To fix this, just remove the comment in newPos. The code will make 'objects' x and y values to what 'this.x' and 'this.y' are in newPos, which will be the new values.
I don't understand this behavior in javascript for inheritance I've always seen it defined like so :
function GameObject(oImg, x, y) {
this.x = x;
this.y = y;
this.img = oImg;
this.hit = new Object();
this.hitBox.x = x;
this.hitBox.y = y;
this.hitBox.width = oImg.width;
this.hitBox.height = oImg.height;
}
Spaceship.prototype = new GameObject();
Spaceship.prototype.constructor = Spaceship;
function Spaceship(){
console.log("instantiate ship");
GameObject.apply(this, arguments);
this.vx = 0;
this.vy = 0;
this.speed = 3;
this.friction = 0.94;
}
But in my case, these lines :
this.hitBox.width = oImg.width;
this.hitBox.height = oImg.height;
When I do a console.log(this) in my Spaceship constructor, I can see that the proto property is set to Spaceship instead of GameObject, if I remove them, it is set to GameObject.
And if I use :
Spaceship.prototype = GameObject.prototype;
I have no more problems with that. The reason that this blocks me is that I have another object with an add() method and it checks that the object inerhits of GameObject with this code :
if(object instanceof GameObject)
I don't understand what those two lines can probably change so that inheritance is broken when they are present and I'm not sure doing inheritance the second way is good. Could someone enlighten me about this please ? :)
If you do
Spaceship.prototype = GameObject.prototype;
Then they both refer to the same object, so you might as well have everything in GameObject, if you add something to Spaceship.prototype, it will be added to GameObject.prototype as well. You can easily test it by adding something to Spaceship.prototype after the assignment. For example, in your case you can see that GameObject.prototype.constructor is actually Spaceship.
As for
Spaceship.prototype = new GameObject();
This invokes the constructor which might have undesired side effects, you rather want to use:
Spaceship.prototype = Object.create(GameObject.prototype);
Where the used Object.create functionality here comes down to:
Object.create = function( proto ) {
function f(){}
f.prototype = proto;
return new f;
};
Modern browsers already have the function though.
It was never properly explained why you were getting weird behavior with this.hitBox (I think that's what you were trying to say).
If you do inheritance by invoking the parent's constructor to create a prototype, that parent's constructor is executed once to create an instance of the parent type, and then all instances of the child type will share that one instance as their prototype.
The problem with this is that if that constructor has any lines that assign mutable objects to this, then those objects will be properties on that prototype and any modifications to those objects will be reflected across all instances of the child type:
Spaceship.prototype = new GameObject();
Spaceship.prototype.constructor = Spaceship;
var sps1 = new Spaceship();
var sps2 = new Spaceship();
sps1.hitBox.x = 9;
sps2.hitBox.x = 12;
console.log(sps1.hitBox.x); // 12 (oh noes! what happened)
console.log(sps2.hitBox.x); // 12
(there are other, similar problems with the "call a constructor to make a prototype" approach, but I'll just leave it here on that point)
#Esailija's suggestion to use Object.create(baseObject) is the first step to solving this problem. It creates a new object whose prototype is baseObject, but without the stuff that is set up in the constructor (This is a good thing, but it needs to be accounted for. Read on...).
As I just said, this will create an object where the initialization logic in the parent's constructor has never run, but in most cases that logic is relevant to the object's functionality. So there is one more thing you need to do, which is to have the child constructor call the parent constructor:
function Spaceship(oImg, x, y) {
// call parent constructor on this object and pass in arguments.
// you could also use default values for the arguments when applicable
GameObject.call(this, oImg, x, y);
// remainder of Spaceship constructor...
}
This will ensure that the parent constructor logic runs separately for every new Spaceship, and carries out the necessary initialization tasks.
function GameObject(oImg, x, y) {
this.x = x;
this.y = y;
this.img = oImg || {width:null, height: null};
this.hitBox = new Object();
this.hitBox.x = x;
this.hitBox.y = y;
this.hitBox.width = this.img.width;
this.hitBox.height = this.img.height;
}
function Spaceship(){
GameObject.apply(this, arguments);
this.vx = 0;
this.vy = 0;
this.speed = 3;
this.friction = 0.94;
}
Spaceship.prototype = new GameObject();
var sps1 = new Spaceship();
var sps2 = new Spaceship();
sps1.hitBox.x = 9;
sps2.hitBox.x = 12;
console.log(sps1.hitBox.x); // 9
console.log(sps2.hitBox.x); // 12
I don't understand this behavior in javascript for inheritance I've always seen it defined like so :
function GameObject(oImg, x, y) {
this.x = x;
this.y = y;
this.img = oImg;
this.hit = new Object();
this.hitBox.x = x;
this.hitBox.y = y;
this.hitBox.width = oImg.width;
this.hitBox.height = oImg.height;
}
Spaceship.prototype = new GameObject();
Spaceship.prototype.constructor = Spaceship;
function Spaceship(){
console.log("instantiate ship");
GameObject.apply(this, arguments);
this.vx = 0;
this.vy = 0;
this.speed = 3;
this.friction = 0.94;
}
But in my case, these lines :
this.hitBox.width = oImg.width;
this.hitBox.height = oImg.height;
When I do a console.log(this) in my Spaceship constructor, I can see that the proto property is set to Spaceship instead of GameObject, if I remove them, it is set to GameObject.
And if I use :
Spaceship.prototype = GameObject.prototype;
I have no more problems with that. The reason that this blocks me is that I have another object with an add() method and it checks that the object inerhits of GameObject with this code :
if(object instanceof GameObject)
I don't understand what those two lines can probably change so that inheritance is broken when they are present and I'm not sure doing inheritance the second way is good. Could someone enlighten me about this please ? :)
If you do
Spaceship.prototype = GameObject.prototype;
Then they both refer to the same object, so you might as well have everything in GameObject, if you add something to Spaceship.prototype, it will be added to GameObject.prototype as well. You can easily test it by adding something to Spaceship.prototype after the assignment. For example, in your case you can see that GameObject.prototype.constructor is actually Spaceship.
As for
Spaceship.prototype = new GameObject();
This invokes the constructor which might have undesired side effects, you rather want to use:
Spaceship.prototype = Object.create(GameObject.prototype);
Where the used Object.create functionality here comes down to:
Object.create = function( proto ) {
function f(){}
f.prototype = proto;
return new f;
};
Modern browsers already have the function though.
It was never properly explained why you were getting weird behavior with this.hitBox (I think that's what you were trying to say).
If you do inheritance by invoking the parent's constructor to create a prototype, that parent's constructor is executed once to create an instance of the parent type, and then all instances of the child type will share that one instance as their prototype.
The problem with this is that if that constructor has any lines that assign mutable objects to this, then those objects will be properties on that prototype and any modifications to those objects will be reflected across all instances of the child type:
Spaceship.prototype = new GameObject();
Spaceship.prototype.constructor = Spaceship;
var sps1 = new Spaceship();
var sps2 = new Spaceship();
sps1.hitBox.x = 9;
sps2.hitBox.x = 12;
console.log(sps1.hitBox.x); // 12 (oh noes! what happened)
console.log(sps2.hitBox.x); // 12
(there are other, similar problems with the "call a constructor to make a prototype" approach, but I'll just leave it here on that point)
#Esailija's suggestion to use Object.create(baseObject) is the first step to solving this problem. It creates a new object whose prototype is baseObject, but without the stuff that is set up in the constructor (This is a good thing, but it needs to be accounted for. Read on...).
As I just said, this will create an object where the initialization logic in the parent's constructor has never run, but in most cases that logic is relevant to the object's functionality. So there is one more thing you need to do, which is to have the child constructor call the parent constructor:
function Spaceship(oImg, x, y) {
// call parent constructor on this object and pass in arguments.
// you could also use default values for the arguments when applicable
GameObject.call(this, oImg, x, y);
// remainder of Spaceship constructor...
}
This will ensure that the parent constructor logic runs separately for every new Spaceship, and carries out the necessary initialization tasks.
function GameObject(oImg, x, y) {
this.x = x;
this.y = y;
this.img = oImg || {width:null, height: null};
this.hitBox = new Object();
this.hitBox.x = x;
this.hitBox.y = y;
this.hitBox.width = this.img.width;
this.hitBox.height = this.img.height;
}
function Spaceship(){
GameObject.apply(this, arguments);
this.vx = 0;
this.vy = 0;
this.speed = 3;
this.friction = 0.94;
}
Spaceship.prototype = new GameObject();
var sps1 = new Spaceship();
var sps2 = new Spaceship();
sps1.hitBox.x = 9;
sps2.hitBox.x = 12;
console.log(sps1.hitBox.x); // 9
console.log(sps2.hitBox.x); // 12
I want to create an instance of a Point with and without the new operator like:
Point(5, 10); // returns { x: 5, y: 10 }
// or
new Point(5, 10); // also returns { x: 5, y: 10 }
I got it working so far with the help of StackOverflow.
function Point() {
if (!(this instanceof Point)) {
var args = Array.prototype.slice.call(arguments);
// bring in the context, needed for apply
args.unshift(null);
return new (Point.bind.apply(Point, args));
}
// determine X and Y values
var pos = XY(Array.prototype.slice.call(arguments));
this.x = pos.x;
this.y = pos.y;
}
But that looks horrible, I am even unshifting null into the array so I can use apply. That just doesn't feel right.
I found a lot of solutions how to achieve it with new constructors and constructor wrappers but I want to keep it as simple as possible (it's just a plain, simple Point).
Is there an easier way to achieve this behaviour?
If you don't mind using ECMAScript 5 functions, Object.create() could help:
function Point()
{ var args = Array.prototype.slice.call(arguments);
if (this instanceof Point) return Point.apply(null, args);
var pos = XY(args);
var result = Object.create(Point.prototype);
result.x = pos.x;
result.y = pos.y;
return result;
}
If you need ECMAScript 3 compatibility, this crazy, convoluted solution is yet another one (note that it's just a wrapper for an internal equivalent of new Point):
function Point()
{ var pos = XY(Array.prototype.slice.call(arguments));
function internalPoint()
{ this.x = pos.x;
this.y = pos.y;
}
internalPoint.prototype = Point.prototype;
return new internalPoint;
}
I don't understand this behavior in javascript for inheritance I've always seen it defined like so :
function GameObject(oImg, x, y) {
this.x = x;
this.y = y;
this.img = oImg;
this.hit = new Object();
this.hitBox.x = x;
this.hitBox.y = y;
this.hitBox.width = oImg.width;
this.hitBox.height = oImg.height;
}
Spaceship.prototype = new GameObject();
Spaceship.prototype.constructor = Spaceship;
function Spaceship(){
console.log("instantiate ship");
GameObject.apply(this, arguments);
this.vx = 0;
this.vy = 0;
this.speed = 3;
this.friction = 0.94;
}
But in my case, these lines :
this.hitBox.width = oImg.width;
this.hitBox.height = oImg.height;
When I do a console.log(this) in my Spaceship constructor, I can see that the proto property is set to Spaceship instead of GameObject, if I remove them, it is set to GameObject.
And if I use :
Spaceship.prototype = GameObject.prototype;
I have no more problems with that. The reason that this blocks me is that I have another object with an add() method and it checks that the object inerhits of GameObject with this code :
if(object instanceof GameObject)
I don't understand what those two lines can probably change so that inheritance is broken when they are present and I'm not sure doing inheritance the second way is good. Could someone enlighten me about this please ? :)
If you do
Spaceship.prototype = GameObject.prototype;
Then they both refer to the same object, so you might as well have everything in GameObject, if you add something to Spaceship.prototype, it will be added to GameObject.prototype as well. You can easily test it by adding something to Spaceship.prototype after the assignment. For example, in your case you can see that GameObject.prototype.constructor is actually Spaceship.
As for
Spaceship.prototype = new GameObject();
This invokes the constructor which might have undesired side effects, you rather want to use:
Spaceship.prototype = Object.create(GameObject.prototype);
Where the used Object.create functionality here comes down to:
Object.create = function( proto ) {
function f(){}
f.prototype = proto;
return new f;
};
Modern browsers already have the function though.
It was never properly explained why you were getting weird behavior with this.hitBox (I think that's what you were trying to say).
If you do inheritance by invoking the parent's constructor to create a prototype, that parent's constructor is executed once to create an instance of the parent type, and then all instances of the child type will share that one instance as their prototype.
The problem with this is that if that constructor has any lines that assign mutable objects to this, then those objects will be properties on that prototype and any modifications to those objects will be reflected across all instances of the child type:
Spaceship.prototype = new GameObject();
Spaceship.prototype.constructor = Spaceship;
var sps1 = new Spaceship();
var sps2 = new Spaceship();
sps1.hitBox.x = 9;
sps2.hitBox.x = 12;
console.log(sps1.hitBox.x); // 12 (oh noes! what happened)
console.log(sps2.hitBox.x); // 12
(there are other, similar problems with the "call a constructor to make a prototype" approach, but I'll just leave it here on that point)
#Esailija's suggestion to use Object.create(baseObject) is the first step to solving this problem. It creates a new object whose prototype is baseObject, but without the stuff that is set up in the constructor (This is a good thing, but it needs to be accounted for. Read on...).
As I just said, this will create an object where the initialization logic in the parent's constructor has never run, but in most cases that logic is relevant to the object's functionality. So there is one more thing you need to do, which is to have the child constructor call the parent constructor:
function Spaceship(oImg, x, y) {
// call parent constructor on this object and pass in arguments.
// you could also use default values for the arguments when applicable
GameObject.call(this, oImg, x, y);
// remainder of Spaceship constructor...
}
This will ensure that the parent constructor logic runs separately for every new Spaceship, and carries out the necessary initialization tasks.
function GameObject(oImg, x, y) {
this.x = x;
this.y = y;
this.img = oImg || {width:null, height: null};
this.hitBox = new Object();
this.hitBox.x = x;
this.hitBox.y = y;
this.hitBox.width = this.img.width;
this.hitBox.height = this.img.height;
}
function Spaceship(){
GameObject.apply(this, arguments);
this.vx = 0;
this.vy = 0;
this.speed = 3;
this.friction = 0.94;
}
Spaceship.prototype = new GameObject();
var sps1 = new Spaceship();
var sps2 = new Spaceship();
sps1.hitBox.x = 9;
sps2.hitBox.x = 12;
console.log(sps1.hitBox.x); // 9
console.log(sps2.hitBox.x); // 12