Accessing property of constructor without creating new instance - javascript

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

Related

java script singleton behavior from session to session

I want to implement java script Singleton in my script.
Some of the variables of the Singleton have the same values for all users, but others will very from user to user.
I want to understand better - is Singleton create one instance for all the session running or every session will manage her own object.
One of the variables will be logger/counter - will all the users/sessions share its value?
My object will look something like this:
var VideoLog = (function () {
/** logger vars **/
this.logger = 0;
this.somevar = null;
this.somefunction = function () {
come code..
}
})();
The Singleton pattern is designed specifically to limit the number of instances of an object to one. This pattern is good for system-wide scripts.
I would suggest using the Constructor pattern. This way you can create a parent object that defines shared fields across objects. Then, create other objects from the parent which can have their own unique fields.
function Cat( breed, age ) {
this.breed = breed;
this.age = age;
}
var tabby = new Cat( "tibs", 3 );
var blue = new Cat( "Thomas", 6 );
tabby.color = 'orange';
blue.color = 'grey';

should I use the constructor or the instance when referencing an object's property from another constructor?

While I am writing a constructors' methods like the "runGame" method of the "Game" constructor, if I need to reference a property of the "GameBoard" constructor should I use the name of the constructor, like this:
function Game(){
this.runGame(){
var someProp = GameBoard.otherProp;
}
}
or do I have to create an instance of the constructor object first and then refer to the instance like this.
var newGameBoard = new GameBoard();
function Game(){
this.runGame(){
var someProp = newGameBoard.otherProp;
}
}
If I've understood your question in the right way, what you need is composition and you need to inject associated instances during construction time:
function Game(gameBoard) {
this.gameBoard = gameBoard;
}
Game.prototype = {
runGame: function() {
// You access injected GameBoard through the
// own Game object's property "this.gameBoard"
var someProperty = this.gameBoard.someProperty;
}
};
var gameBoard = new GameBoard();
var game = new Game(gameBoard);
Further reading:
Dependency injection (Wikipedia)
Object composition (Wikipedia)
If every Game has a GameBoard, it should be a property:
function Game(){
this.board=new Board();
}
Game.prototype.runGame=function(){//real inheritance
var someProp = this.board.otherProp;
};
If the GameBoard(s) belong to the Game in your logic, here's how I'd do it
var Game = function(params) {
this.options = params.options; // it could prove useful to instanciate a game using a set of rules
this.gameBoards = params.gameBoards; // Already instanciated gameBoard(s)
this.activeGameBoard = null; // if there are many gameboards it might be a good idea to keep track of the one that's currently active
this.prop = '';
// ... Initialize all the properties you need for your Game object
}
Game.prototype = {
runGame: function(gameBoardIndex) {
this.activeGameBoard = this.gameBoards[index];
this.someProp = this.activeGameBoard.someProp;
}
}
I know I'm assuming a lot of things but I can't help it, it reminds me the only project I worked on that involved games and gameboards :p

What is the best way to define dependent variables in an object?

In the Google developers recommendation for optimizing JavaScript code, they mention that the best way to declare/initialize new variables for object is to use the prototype. For instance, instead of:
foo.Bar = function() {
this.prop1_ = 4;
this.prop2_ = true;
this.prop3_ = [];
this.prop4_ = 'blah';
};
Use:
foo.Bar = function() {
this.prop3_ = [];
};
foo.Bar.prototype.prop1_ = 4;
foo.Bar.prototype.prop2_ = true;
foo.Bar.prototype.prop4_ = 'blah';
However, in my case I have a dependency between variables, for instance:
var appv2 = function(){
this.start(this.person, this.car);
};
appv2.prototype.toWhom = 'Mohamed';
appv2.prototype.person = new person(this.toWhom);
appv2.prototype.car = new car();
appv2.prototype.start = function(person, car){
console.log('start for appv2 is called');
person.sayHello('me app v2');
car.brand();
};
new appv2();
Using this.toWhom outside of the main constructor body or a method function of the object will yield undefined. To solve this I could use appv2.prototype.toWhom instead of this.toWhom or I could declare my dependent variables inside of the main constructor body.
But I would like to know what is the best way, in terms of performance, to accomplish this?
Thanks
To reference toWhom while creating person, you can either store the value in a separate variable:
var toWhom = appv2.prototype.toWhom = 'Mohamed';
appv2.prototype.person = new person(toWhom);
Or, reference it from the prototype, as you suspected:
appv2.prototype.person = new person(appv2.prototype.toWhom);
The reason this.toWhom is undefined is because this doesn't refer to an instance of appv2 there.

How to convert javascript object variable into a class

How do I define a class I can instatiate later?
I wrote myself a rotator class using jquery which looks like:
var Rotator =
{
Loop: null,
init: function(identifierName)
{
........
}
}
If i want to have one rotator on my page it's good. I just call Rotator.init() and it's ready.
However when I want to have 3 rotators i got to define 3 times the whole class code changing its name.
Way easier it would be if I could just do
Instance1 = new rotator;
Instance2 = new rotator;
Instance3 = new rotator;
The following is what your object literal might look like as a re-usable Named Function that can be instantiated multiple times:
var Rotator = function(name) {
this.Name = name;
this.Loop = null;
this.init = function(identifierName)
{
this.Name = identifierName;
};
};
// usage:
var foorotator = new Rotator('foo');
var barrotator = new Rotator('bar');
alert(foorotator.Name);
alert(barrotator.Name);
http://jsfiddle.net/JzWCL/
After Edit:
http://jsfiddle.net/mPzsq/
Xander's solution looks like an acceptable form for a class-like object used only once. If you plan to subclass or multiply instantiate it, however, you should apply methods to the prototype rather than defining them within the main class (constructor) function. For example:
var Rotator = function(name) {
//run your initialization logic inside this constructor function
this.Name = name;
this.Loop = null;
}
Rotator.prototype.someMethod = function() {
//method code
}
var rotator1 = new Rotator('foo');
var rotator2 = new Rotator('bar');
The reason to use this structure is to prevent the methods from being reconstructed every time the class is instantiated. By applying the methods to the prototype, they will be shared between all instances of the class.
I've found this to be a helpful reference for some basics of JavaScript class definition:
3 Ways to Define a JavaScript Class

JavaScript creating new instance of objects

So I am designing a grade book interface and I have a course defined as:
<script>
course = new Object();
var name;
var gradingareas;
var finalgrade;
</script>
then later I want to create a new instance:
var gradingareas = new Array("Homework", "Classwork", "Exams");
course1 = new course("CS1500", gradingareas, 85);
I have also tried without the var in front to no avail. I get an "Uncaught TypeError: Object is not a function" I am very new to javascript so I don't even know if Im going about this the correct way. Any help is appreciated Thanks.
Your existing code:
// Creates a new, empty object, as a global
course = new Object();
// Creates three new variables in the global scope.
var name;
var gradingareas;
var finalgrade;
There is no connection between the variables and the object.
It looks like you want something more like:
function Course(name, gradingareas, finalgrade) {
this.name = name;
this.gradingareas = gradingareas;
this.finalgrade = finalgrade;
}
Then:
var course1 = new Course("CS1500", gradingareas, 85);
Note the use of a capital letter for naming the constructor function. This is a convention in the JS community.
JS is prototypical, rather than class based and if you are new to it there are advantages to learning this immediately rather than trying to mush classical inheritance models from it, however, classical inheritance is alive and well in JS.
Anyhow, to answer how you would access your variables:
course1.name works fine with the example above.
If you wanted to privatise your data you could take this approach using closure:
var Course = function(name, grade) {
// Private data
var private = {
name: name,
grade: grade
}
// Expose public API
return {
get: function( prop ) {
if ( private.hasOwnProperty( prop ) ) {
return private[ prop ];
}
}
}
};
Then instantiate a new object:
var course = new Course('Programming with JavaScript', 'A');
and start using all that private data:
course.get('name');
Of course, you'd probably want setters to manipulate that data too ;)
The code that you described does the following:
// Declares a memory variable called course and stores and object in it
var course = new Object();
// Declares three variables
var name;
var gradingareas;
var finalgrade;
These declared variables aren't automatically connected to the object. If you want these properties declared on the object you have 2 options:
Declare them as properties of the object
Declare them on the prototype of of the object
Example1: declare them as properties of the object:
// Declares a memory variable called course and stores and object in it
var course = new Object();
// Access or create new properties with . or [] operator
course.name = 'math';
course.gradingareas = 'muliple';
course['finalgrade'] = 'A'
console.log(course);
Example2: Declare them on the prototype:
// Create a constructor function
function Course (name, grade) {
this.name = name;
this.grade = grade;
}
// course is added on the prototype
Course.prototype.gradingareas = 'some gradingareas';
// the name and the grade are added on the object itself
var course = new Course ('willem', 10);
console.log(course);
To create a very simple object with constructor and default values, you can do :
//My object with constructor
var myObjectWithConstrutorFunction = {
//construtor function with default values in constructor
myConstrutor: function(Name = 'bob', Age = 18){
this.Name = name;
this.Age = age;
}
};
// instance
var myInstance = new myObjectWithConstrutorFunction.myConstrutor();
// show on console
console.log('object with constructor function: ', myInstance);
// show properties
console.log(myInstace.Name, myInstance.Age);
PS : It's a good practice create a constructor's name with the same name of the class, if you are creating a external class.

Categories

Resources