I'm trying to write some objects using JavaScript. I have 1 small object that appears to be working but this object needs a multi-dimensional array.
When I try to use this snippet of this object my browser crashes...
Are there any good tutorials on how to write objects in javascript?
function map(sizeX, sizeY)
{
var cityArr = new Array();
this.sizeX = sizeX;
this.sizeY = sizeY;
this.generateCity = generateCity;
var cityXY = new Array();
function generateCity(cityNum)
{
alert(cityNum);
}
}
When I call this, it fails when I add the call to generateCity method my browser cashes.
var objMap = new map();
//objMap.generateCity(2);
What am I doing wrong?
First off, some JavaScript best practices:
use [] to create a new array, not new Array(),
use capital letters for constructor functions, so function Map(...) {...}, not map(...),
don't reference functions before declaring them, so put your function generateCity(cityNum) before your this.generateCity = generateCity,
use console.log, not alert,
if you're building an object, define your object as one by putting its function on its prototype.
That means doing this:
function Map(sizeX, sizeY)
{
this.sizeX = sizeX;
this.sizeY = sizeY;
// you're not using these arrays. Why are they in your example code?
var cityArr = [],
cityXY = [];
}
Map.prototype = {
sizeX: 0, // Some default values, shared by all instances
sizeY: 0, // unless overriden in the constructor function.
generateCity: function(cityNum) {
// let's not block the entire page by using alert.
console.log("cityNum: " + cityNum);
}
}
So, with that said, this code works just fine, as can be seen on http://jsfiddle.net/mtr24 (run with your console open, and you'll see "cityNum: 2" being printed.
Related
How to fix this issue?
// Add to the element's handler list, delegates in front
if ( selector ) {
handlers.splice( handlers.delegateCount++, 0, handleObj );
} else {
handlers.push( handleObj );
}
push() is an operation off of an array object such as:
var x = [];
var y = new Array();
x.push("me");
y.push("you");
To tell if a variable is an array you can do console.log(typeof [variable]); to see what type it is, or alternatively just console log the variable to see the contents.
If you are not using an array, but are using a javascript object, you should add elements to it via basic assignment. Example:
var x = {}; //this works as an object
x.myNewVariable = "My new value";
After which you will be able to use and access that variable off of the object. If you later want to remove that you can do so by:
delete x.myNewVariable;
Is it possible to access properties of a constructor object/function without first creating an instance from it?
For example, let's say I have this constructor:
function Cat() {
this.legs = 4;
};
And now – without creating a new cat instance – I want to know what value of legs is inside the constructor. Is this possible?
(And I'm not looking for stuff like: var legs = new Cat().legs. (Let's say the instantiation of a new Cat is super CPU expensive for some reason.))
Does something like this count?
function Cat() {
this.legs = 4;
}
var obj = {};
Cat.call(obj);
console.log(obj.legs); // 4
This is even more expensive:
console.log(parseInt(Cat.toString().match(/this\.legs\s*=\s*(\d+)/)[1]));
In your scenario, leg is an instance variable, which means that an object instance is needed in order to access it.
You can make it a pseudo-class variable (see class variable in Javascript), you should be able then to access it without calling the function (instantiating the object).
There's a hundred ways to do this, but the static default pattern below is as good as any of them:
function Cat(opts) {
var options = opts || {};
this.legs == options.legs || Cat.defaults.legs;
};
Cat.defaults = {
legs: 4
}
var myCat = new Cat({legs:3}); //poor guy
var normalNumberOfCatLegs = Cat.defaults.legs;
In short, no you can't access that variable without creating an instance of it, but you can work around it:
Global Variable
Assuming 'legs' may vary as the application runs, you may want to create a "global" variable by assigning legs to 'window', an object that will exist throughout the life of the page:
window.legs = 4; // put this at the top of your script
Then throughout the course of the application, you can change this until you're ready to use it in Cats():
window.legs = user_input;
Global Object
You could even assign an object to window, if you want Cats to have other, alterable attributes:
window.Cat = {};
window.Cat.legs = 4;
window.Cat.has_tail = true;
window.Cat.breeds = ["siamese","other cat breed"];
How to use Globals
Then, when a Cat object is created later on, you can pull the data from window to create an instance of Cat:
function Cat(){
this.legs = window.legs;
//or
this.legs = window.Cat.legs;
}
// cat.js
function Cat() {
}
Cat.prototype.legs = 4;
// somescript.js
var legs = Cat.prototype.legs
var cat = new Cat();
console.log(legs, cat.legs); // 4, 4
I apologize for this question, just starting to learn Javascript.
I have 2 methods:
Manager.prototype.filters = function () {
var user = [];
...
Manager.prototype.filters_main = function () {
var user = [];
...
I need to make the property 'user' available to the 2 methods (filters, filters_main). So that they can use the shared variable (user).
How it is possible to write?
You have to understand the prototype-based inheritance here.
var Manager = function() {
this.user = [];
}
var manager = new Manager();
These lines will define a Manager constructor function and create a new object. When you call the new Manager(), what happens is:
a new, empty, object is created: {}.
the code inside the constructor will run with this new, empty, object being the value of this. So, it will set the user property of the new object ({}) to be an empty array.
the __proto__ property of the new object will be set to the value of Manager.prototype. So, this happens without you seeing: manager.__proto__ = Manager.prototype.
Then, you want to define new methods on your prototype objects, using the inheritance. Keep in mind that the prototype is a plain JS object. Not a constructor, but an object. So every object created from the Manager function will have its __proto__ property set to the same object.
Then, you start defining new methods on the prototype object, like the filters function. When you, later, call manager.filters(), it will first look up its own properties for the filters function and won't find it. So, then, it will go for its prototype properties, and there if will find it. manager will then run the filters function that was defined on the prototype, but using itself (manager) as the context, as the this inside the function.
So, to use your user property inside the filters function, all you have to do is:
Manager.prototype.filters = function () {
this.user = ...;
}
Manager.prototype.filters_main = function () {
this.user = ...;
}
and you'll be manipulating the same user property defined when the object was constructed.
Define the variable in your Manager definition:
function Manager() {
this.user = [];
}
And now you should be able to use it in your filter functions:
Manager.prototype.filters = function() {
// Use it:
if (this.user.indexOf(...) != -1) {
...
}
};
Then you can continue as normal:
var manager = new Manager();
manager.user = ["user1", "user2"];
var filters = manager.filters();
Add it to the body:
function Manager() {
this.user = [];
}
Manager.prototype.filters = function () {
alert(this.user)
}
var m = new Manager();
m.user = [11,22,33]
m.filters();
I am trying to populate an object by using a JavaScript class. I am not even sure if I am doing it correctly, I am very new to JavaScript OOP.
var ImagesViewModel = {}; // Global object
function ImagesClass() {
this.addImage = function (iUrl) {
ImagesViewModel.push({ "ImageUrl": iUrl }) //< Error is here
}
}
var k = new ImagesClass()
k.addImage("http://www.yahoo.com")
k.addImage("http://www.xbox.com")
Basically I need an easy way to populate ImagesViewModel with multiple properties. Do I need to specify properties within ImagesViewModel? Maybe I can do all of this without having to specify a global variable?
I am getting the error
Object has no method PUSH
What you want is an array and not an object, push is a method on Array prototype and you are trying to use it on object.
Change:
var ImagesViewModel = {};
To:
var ImagesViewModel = [];
You can do it this way as well so that each instance of ImagesClass has its own set of images.
function ImagesClass() {
var _images = [];
this.addImage = function (iUrl) {
_images.push({ "ImageUrl": iUrl }) //< Error is here
}
this.getImages = function(){
return _images;
}
}
and use it as:
var k = new ImagesClass();
k.addImage("http://www.yahoo.com");
k.addImage("http://www.xbox.com");
var ImagesViewModel = k.getImages(); //You can either set it directly or as a property of object
console.log(ImagesViewModel);
Demo
the push method is only for Arrays, here you are trying to push() to an object, which is why it isn't working.
You will need to change var ImagesViewModel = {}; to var ImagesViewModel = [];
From a design perspective, you probably don't want your viewmodel to just be a flat array (even though you declared it as an object, as other posters pointed out).
I'd suggest declaring an array declaration to hold the images inside of your ImagesViewModel object.
var ImagesViewModel = { // ViewModel generic OBJECT
this.Images = new Array(); // prototype ARRAY object
};
function ImagesClass() {
this.addImage = function (iUrl) {
ImagesViewModel.Images.push({ "ImageUrl": iUrl })
}
}
Let's say I have some class called loopObject and I initialize every object through something like var apple = new loopObject(); Is there anyway to loop through all objects of a class so that some function can be performed with each object as a parameter? If there isn't a direct method, is there a way to place each new object into an array upon initialization?
You can make an array that contains every instance, like this:
function LoopObject() {
LoopObject.all.push(this);
}
LoopObject.all = [];
However, it will leak memory - your instances will never go out of scope.
function loopObject(){
this.name = 'test'
};
var list = [], x = new loopObject, y = new loopObject;
list.push(x)
list.push(y)
for ( var i = list.length; i--; ) {
alert( list[i].name )
}
var allObjects [] = new Array();
function loopObject() {
...
allObjects.push(this);
}
Then one can loop through all elements of allObjects as necessary using allObjects.length.