I understand requiring modules and what not but I would like to have instances of the module to use, kind of like an instance of a class for a java project or whatever. I have this code in my app.js:
var number = require("./number.js");
var numbers = [number.setNumber(2),
number.setNumber(3),
.....];
I have inside the number.js:
var number = -1;
exports.setNumber(num){
number = num;
}
exports.getNumber(){
return number;
}
I hope that it is sort of clear what I'm trying to do here, but I either can't find anywhere that it is explained on google, or I'm not sure what question to ask...so I hope this isn't a duplicate.
QUESTION: How do I create instances of modules/Can I create instances of modules?
Answering myself because although the answers given helped they were incomplete.
I created what seems like a javascript class similar to an answer already given that has a constructor and all other "class methods" as prototypes. Key piece though was to export it.
var myNumber = function(num) {
this.num = num
}
myNumber.prototype.setNumber = function(num) {
this.num = num
}
myNumber.prototype.getNumber = function() {
return this.num
}
module.exports = myNumber
Then, in the node its being required in I have:
var myNumber = require('./number.js');
var numbers = [ new myNumber(2),
new myNumber(3),
new myNumber(3),
new myNumber(4),
new myNumber(4),
new myNumber(5),
new myNumber(5),
new myNumber(6),
new myNumber(6),
new myNumber(8),
new myNumber(8),
new myNumber(9),
new myNumber(9),
new myNumber(10),
new myNumber(10),
new myNumber(11),
new myNumber(11),
new myNumber(12)];
This is what gives me the 20 or so different myNumber objects I was looking for. I don't know if I'm using the module.exports = myNumber correctly, but it works.
Modules are just a way to organize your code. The object, or another type, that you export from module by module.exports = is the thing, that you requiring with require
So you want something like Java Class, you can create a constructor
var Number = function(num) {
this.num = num
}
Number.prototype.setNumber = function(num) {
this.num = num
}
Number.prototype.getNumber = function() {
return this.num
}
and in your other modules you can create a new instance of Number with new keyword
var Number = require('./number.js')
var myNum = new Number(3)
myNum.setNumber(4);
// ... so on
Related
I'm really new to the JavaScript sooo...
I have a class:
var warrior = function(HP) {
this.health = HP;
}
And when I create a new warrior:
var somebody = new warrior(50);
I'd like to give the name "somebody" to the new element. How can I do it?
You cannot. Variable names are meaningless to the program functionality. If you care about the name, use a string and pass it as an argument.
Something like this maybe:
var warrior = function(HP) {
this.health = HP;
}
warrior.prototype.name;
var somebody = new warrior(50);
somebody.name = 'somebody';
console.log(somebody);
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.
Say I have this code:
function ParentClass()
{
var anArray = [ ];
this.addToArray = function(what)
{
anArray.push(what);
console.log(anArray);
};
}
FirstSubClass.prototype = new ParentClass();
FirstSubClass.prototype.constructor = FirstSubClass;
function FirstSubClass()
{
this.addToArray('FirstSubClass');
}
SecondSubClass.prototype = new ParentClass();
SecondSubClass.prototype.constructor = SecondSubClass;
function SecondSubClass()
{
this.addToArray('SecondSubClass');
}
When I run new FirstSubClass() I see a single value array in the console. And when I run new SecondSubClass(), again, I see a single value array.
However, why is it when I run them again (i.e. new FirstSubClass(); new SecondSubClass();) I then see the arrays added to rather than new ones being created?
The rationale here is that I'm creating new instances of a class, therefore why are they sharing the same private property?
How can I avoid this so when I do, for e.g., new FirstSubClass() I then see a single value array no matter how many times I create a new instance of the class?
Keep in mind that you've only called new ParentClass() once for each subclass. That means that the private array variable is part of the prototype object for those subclasses. There's only one prototype object, so there's only one array (per subclass).
Each call to new FirstSubClass() generates a new instance that shares the same prototype object. The call to addToArray() therefore adds an element to that same array that was created when the prototype object was created.
edit — if you want per-instance arrays, you'd have to do something like this:
function ParentClass() {
this.addToArray = function(value) { this.instanceArray.push(value); };
};
function FirstSubClass() {
this.instanceArray = [];
this.addToArray("First");
}
FirstSubClass.prototype = new ParentClass();
FirstSubClass.prototype.constructor = FirstSubClass;
First, sub-classing in JS is typically a bad idea, because people think that they're getting extension, where every instance has its own copy of properties and methods...
...really, they're getting public static access to the parent's stuff.
Even better, that public static stuff has no access to the encapsulated variables, so there's really no manipulation of private data, unless you're using private functions (with a public interface) to pass data to and collect return values from, the public static stuff.
var Parent = function () {
this.static_prop = 0;
this.static_method = function (num) { this.static_prop += 1; return num + this.static_prop; };
};
var Child = function (num) {
this.public_func = function () { num = this.static_method(num); };
};
Child.prototype = new Parent();
var child = new Child(13);
child.public_func();
Just calling this.static_method wouldn't help, because it would have 0 access to num, which means that you're wrapping things which you inherited to grant them access to use private data as inputs, which means that you're doing most of the writing you'd be doing anyway, regardless of inheritance, because your expectations of .prototype were backwards.
Might I suggest Dependency Injection, instead?
Component-based programs?
var Iterator = function () {
var count = 0,
min = 0,
max = 0,
reset = function () { count = min; },
next = function () { count = count >= max ? min : count; return count += 1; },
set_min = function (val) { min = val; },
set_max = function (val) { max = val; },
public_interface = { reset : reset, count : count, set_min : set_min, set_max : set_max };
return public_interface;
},
Thing = function (iter) {
var arr = [],
currentObj = null,
nextObj = function () {
currentObj = arr[iter.next()];
},
add = function (obj) {
arr.push(obj); iter.set_max(arr.length);
},
public_interface = { next : nextObj, add : add };
return public_interface;
};
var thing = Thing(Iterator());
thing.add({});
thing.next();
It's a convoluted example, but now every instance is going to be given exactly what it needs to do its job (because the constructor requires it -- or you can add the dependency later, through a public method, or as a public-property).
The interfaces for each module can now also get as simple and as clean as you'd like, as you don't have to wrap unexpected static-helpers to get private data...
Now you know what's private, you know what you're extending to the public, and you have clean ins and outs wherever you want to put them.
You are only constructing a new instance of ParentClass once per subclass and that is to apply it to your prototype. If you want each instance to have its own copy of the private array and its own copy of the function "addToArray" you will need to invoke the ParentClass constructor function within your other objects constructors:
function ParentClass(){
var anArray = [ ];
this.addToArray = function(what){
anArray.push(what);
console.log(anArray);
};
}
FirstSubClass.prototype = new ParentClass();
FirstSubClass.prototype.constructor = FirstSubClass;
function FirstSubClass(){
//call the parents constructor where "this" points to your FirstSubClass instance
ParentClass.call( this );
this.addToArray('FirstSubClass');
}
SecondSubClass.prototype = new ParentClass();
SecondSubClass.prototype.constructor = SecondSubClass;
function SecondSubClass(){
ParentClass.call( this );
this.addToArray('SecondSubClass');
}
try this:
http://jsfiddle.net/3z5AX/2/
function ParentClass()
{
var anArray = [ ];
this.addToArray = function(what)
{
anArray.push(what);
document.getElementById("i").value = anArray;
};
}
//FirstSubClass.prototype = new ParentClass();
FirstSubClass.prototype.constructor = FirstSubClass;
function FirstSubClass()
{
this.parent = new ParentClass()
this.parent.addToArray('FirstSubClass');
}
var q = new FirstSubClass();
var r = new FirstSubClass();
All Subclasses share the same parent class, thus the same private anArray
The solution is to use the Mixin pattern.
// I have the habbit of starting a mixin with $
var $AddToArray = function(obj) {
var array = [];
obj.addToArray = function(what) {
array.push(what);
console.log(array);
};
}
var FirstClass = function() {
$AddToArray(this);
}
var SecondClass = function() {
$AddToArray(this);
}
If i have a Javascript object defined as:
function MyObj(){};
MyObj.prototype.showAlert = function(){
alert("This is an alert");
return;
};
Now a user can call it as:
var a = new MyObj();
a.showAlert();
So far so good, and one can also in the same code run another instance of this:
var b = new MyObj();
b.showAlert();
Now I want to know, how can I hold the number of instances MyObj?
is there some built-in function?
One way i have in my mind is to increment a global variable when MyObj is initialized and that will be the only way to keep track of this counter, but is there anything better than this idea?
EDIT:
Have a look at this as suggestion here:
I mean how can I make it get back to 2 instead of 3
There is nothing built-in; however, you could have your constructor function keep a count of how many times it has been called. Unfortunately, the JavaScript language provides no way to tell when an object has gone out of scope or has been garbage collected, so your counter will only go up, never down.
For example:
function MyObj() {
MyObj.numInstances = (MyObj.numInstances || 0) + 1;
}
new MyObj();
new MyObj();
MyObj.numInstances; // => 2
Of course, if you want to prevent tampering of the count then you should hide the counter via a closure and provide an accessor function to read it.
[Edit]
Per your updated question - there is no way to keep track of when instances are no longer used or "deleted" (for example by assigning null to a variable) because JavaScript provides no finalizer methods for objects.
The best you could do is create a "dispose" method which objects will call when they are no longer active (e.g. by a reference counting scheme) but this requires cooperation of the programmer - the language provides no assistance:
function MyObj() {
MyObj.numInstances = (MyObj.numInstances || 0) + 1;
}
MyObj.prototype.dispose = function() {
return MyObj.numInstances -= 1;
};
MyObj.numInstances; // => 0
var a = new MyObj();
MyObj.numInstances; // => 1
var b = new MyObj();
MyObj.numInstances; // => 2
a.dispose(); // 1 OK: lower the count.
a = null;
MyObj.numInstances; // => 1
b = null; // ERR: didn't call "dispose"!
MyObj.numInstances; // => 1
Create a static property on the MyObj constructor called say count and increment it within the constructor itself.
function MyObj() {
MyObj.count++;
}
MyObj.count = 0;
var a = new MyObj;
var b = new MyObj;
alert(MyObj.count);
This is the way you would normally do it in say Java (using a static property).
var User = (function() {
var id = 0;
return function User(name) {
this.name = name;
this.id = ++id;
}
})();
User.prototype.getName = function() {
return this.name;
}
var a = new User('Ignacio');
var b = new User('foo bar');
a
User {name: "Ignacio", id: 1}
b
User {name: "foo bar", id: 2}
Using ES6 Classes MDN syntax - we can define a static method:
The static keyword defines a static method for a class. Static methods are called without instantiating their class and cannot be called through a class instance. Static methods are often used to create utility functions for an application.
class Item {
static currentId = 0;
_id = ++Item.currentId; // Set Instance's this._id to incremented class's ID
// PS: The above line is same as:
// constructor () { this._id = ++Item.currentId; }
get id() {
return this._id; // Getter for the instance's this._id
}
}
const A = new Item(); // Create instance (Item.currentId is now 1)
const B = new Item(); // Create instance (Item.currentId is now 2)
const C = new Item(); // Create instance (Item.currentId is now 3)
console.log(A.id, B.id, C.id); // 1 2 3
console.log(`Currently at: ${ Item.currentId }`); // Currently at: 3
PS: if you don't want to log-expose the internal currentId property, make it private:
static #currentId = 0;
_id = ++Item.#currentId;
Here's an example with constructor and without the getter:
class Item {
static id = 0;
constructor () {
this.id = ++Item.id;
}
getID() {
console.log(this.id);
}
}
const A = new Item(); // Create instance (Item.id is now 1)
const B = new Item(); // Create instance (Item.id is now 2)
const C = new Item(); // Create instance (Item.id is now 3)
A.getID(); B.getID(); C.getID(); // 1; 2; 3
console.log(`Currently at: ${ Item.id }`); // Currently at: 3
what about such method?
var Greeter = (function ()
{
var numInstances;
function Greeter(message)
{
numInstances = (numInstances || 0) + 1;
this.greeting = message;
}
Greeter.prototype.greet = function ()
{
return "Hello, " + this.greeting;
};
Greeter.prototype.getCounter = function ()
{
return numInstances;
};
return Greeter;
})();
var greeter = new Greeter("world");
greeter.greet();
greeter.getCounter();
var newgreeter = new Greeter("new world");
newgreeter.greet();
newgreeter.getCounter();
greeter.getCounter();
Keeping a global count variable and incrementing every time is an option. Another option is to call counter method after each instance creation by hand (the worst thing I could imagine). But there is another better solution.
Every time we create an instance, the constructor function is being called. The problem is the constructor function is being created for each instance, but we can have a count property inside __proto__ which can be the same for each instance.
function MyObj(){
MyObj.prototype.addCount();
};
MyObj.prototype.count = 0;
MyObj.prototype.addCount = function() {
this.count++;
};
var a = new MyObj();
var b = new MyObj();
This is our a and b variables after all:
Eventually, JS is going to have built-in proxy capability, which will have low-level access to all kinds of things which happen in the background, which will never be exposed to front-end developers (except through the proxy -- think magic-methods in languages like PHP).
At that time, writing a destructor method on your object, which decrements the counter might be entirely trivial, as long as support for destruction/garbage-collection as a trigger is 100% guaranteed across platforms.
The only way to currently, reliably do it might be something like creating an enclosed registry of all created instances, and then manually destructing them (otherwise, they will NEVER be garbage-collected).
var Obj = (function () {
var stack = [],
removeFromStack = function (obj) {
stack.forEach(function (o, i, arr) {
if (obj === o) { arr.splice(i, 1); }
makeObj.count -= 1;
});
};
function makeObj (name) {
this.sayName = function () { console.log("My name is " + this.name); }
this.name = name;
this.explode = function () { removeFromStack(this); };
stack.push(this);
makeObj.count += 1;
}
makeObj.checkInstances = function () { return stack.length; };
makeObj.count = 0;
return makeObj;
}());
// usage:
var a = new Obj("Dave"),
b = new Obj("Bob"),
c = new Obj("Doug");
Obj.count; // 3
// "Dave? Dave's not here, man..."
a.explode();
Obj.count; // 2
a = null; // not 100% necessary, if you're never going to call 'a', ever again
// but you MUST call explode if you ever want it to leave the page's memory
// the horrors of memory-management, all over again
Will this pattern do what you want it to do?
As long as:
you don't turn a into something else
you don't overwrite its explode method
you don't mess with Obj in any way
you don't expect any prototype method to have access to any of the internal variables
...then yes, this method will work just fine for having the counter work properly.
You could even write a general method called recycle, which calls the explode method of any object you pass it (as long as its constructor, or factory, supported such a thing).
function recycle (obj) {
var key;
obj.explode();
for (key in obj) { if (obj.hasOwnProperty(key)) { delete obj[key]; } }
if (obj.__proto__) { obj.__proto__ = null; }
}
Note - this won't actually get rid of the object.
You'll just have removed it from the closure, and removed all methods/properties it once had.
So now it's an empty husk, which you could reuse, expressly set to null after recycling its parts, or let it be collected and forget about it, knowing that you removed necessary references.
Was this useful?
Probably not.
The only time I really see this as being of use would be in a game where your character might only be allowed to fire 3 bullets at a time, and he can't shoot a 4th until the 1st one on screen hits someone or goes off the edge (this is how, say, Contra worked, in the day).
You could also just shift a "disappeared" bullet off the stack, and reuse that bullet for any player/enemy by resetting its trajectory, resetting appropriate flags, and pushing it back onto the stack.
But again, until proxies allow us to define "magic" constructor/destructor methods, which are honoured at a low-level, this is only useful if you're going to micromanage the creation and destruction of all of your own objects (really not a good idea).
My solution is creating an object store instance count and a function to increase them in prototype.
function Person() {
this.countInst();
}
Person.prototype = {
constructor: Person,
static: {
count: 0
},
countInst: function() {
this.static.count += 1;
}
};
var i;
for (i = 0; i < 10; i++) {
var p = new Person();
document.write('Instance count: ');
document.write(p.static.count);
document.write('<br />');
}
Here is my plunker: https://plnkr.co/edit/hPtIR2MQnV08L9o1oyY9?p=preview
class Patient{
constructor(name,age,id){
Object.assign(this,{name, age, id});
}
static patientList = []; // declare a static variable
static addPatient(obj){
this.patientList.push(...obj); // push to array
return this.patientList.length; // find the array length to get the number of objects
}
}
let p1 = new Patient('shreyas',20, 1);
let p2 = new Patient('jack',25, 2);
let p3 = new Patient('smith',22, 3);
let patientCount = Patient.addPatient([p1,p2,p3]); // call static method to update the count value with the newly created object
console.log(Patient.patientList);
console.log(patientCount);
I'm on my way through Object Oriented Javascript, and I can't help but feel I've missed the boat on a given exercise. So what I'm looking for here is pointers on how I can improve my code or understanding of Constructors. Here was the challenge:
Imagine the String() constructor
didn't exist. Create a constructor
function MyString() that acts like
String() as closely as possible.
You're not allowed to use any built-in
string methods or properties, and
remember that String() doesn't exist.
You can use this code to test your
constructor:
--
var s = new MyString('hello');
s.length(); s[0]; s.toString();
s.valueOf(); s.charAt(1);
s.charAt('2'); s.charAt('e');
s.concat(' world!'); s.slice(1,3);
s.slice(0,-1); s.split('e);
s.split('l'); s.reverse();
And here was my response, which fails on one or two accounts, but I'm more interested in the actual structure of it. Am I completely off-base? Is there somewhere I can view the actual String constructor implemented by browsers to compare?
function MyString(string){
a = string.split("");
this.length = a.length;
this.toString = function(){
return a.join("");
};
this.valueOf = function(){
if(a.length > 0 && string !== 0 && string !== false && string !== undefined){
return true;
} else {
return false;
}
};
this.charAt = function(index){
return a[index];
};
this.concat = function(addition){
return string + addition;
};
this.slice = function(begin, end){
var a2 = new Array();
if(end < 0){
end = parseInt(a.length) + end;
}
for(y = begin;y<end;y++){
a2 += a[y];
}
return a2;
};
this.split = function(splitter){
spPos = parseInt(a.indexOf(splitter));
var split1 = a.slice(0,spPos);
var split2 = a.slice(spPos + 1, a.length);
var joined = new Array();
return joined.concat(split1.join(""), split2.join(""));
};
this.reverse = function(){
var ar = a.reverse();
return ar.join("");
};
return this;
}
I'm headed to bed, but I'll be up and responding in the morning. Thanks so much for any guidance you can give on this issue.
A quick point about the structure of your class, as mentioned before.
Your class is written in such a way so that all the methods are inside the constructor. So when you initialise a new class all the methods are regenerated. Thus if you have more than one instance of class MyString on the page this won't be the most efficient technique. You should consider using the prototyping technique instead. So your constructor would simply become:
function MyString(string){
a = string.split("");
this.length = a.length;
}
Your methods are then declared outside the constructor and as such are not regenerated each time a new instance of MyString is created.
MyString.prototype.toString = function(){ return a.join(""); }
MyString.prototype.charAt = function(index){ return a[index]; }
Firstly, browsers generally have the String implementation in some kind of native code. You won't be able to view that code.
Considering that you are keen on improving your code, is it ok for you not make 'a' private, or may be at least to have a function that returns a. This depends on your requirements basically. The reason I ask is that it is really important to note the number of functions created each time your constructor is called. To avoid this you should move these functions into the prototype of the MyString function, so that the functions are used by all instances of MyString. That way you won't be creating multiple instances of the same function. But again this depends on whether you are ok letting 'a' be accessible outside the function (but at the same time it makes a huge difference in the number of function objects created).
I think the answer marked as correct is not entirely right. If you do:
var hello = new MyString('hello');
var bye = new MyString('bye');
hello.toString() // returns "bye"
Maybe the solution to it could be:
function MyString(string){
this.a = string.split("");
this.length = this.a.length;
}
MyString.prototype.toString = function(){ return this.a.join(""); }
MyString.prototype.charAt = function(index){ return this.a[index]; }