The variable that stores the constructor function in JavaScript - javascript

My question might be basic but I could not really find a good explanation anywhere. I am new to JavaScript and I am confused about the variable that stores the constructor function and it's functionality, in this example, var MyObject.
The constructor function:
var MyObject = function(){
var self ={
x:250,
y:250
}
return self;
}
The question is, if I do something like below after the above code (outside the constructor function):
MyObject.list = {};
MyObject.connect = function(data){
//do something
};
What exactly is the meaning of this? will it add the new method and the new list to all instances of MyObject?
Is it equivalent to writing the additional list and connect method within the constructor function itself like this:
var MyObject = function(){
var self ={
x:250,
y:250
}
self.list = {};
self.connect = function(data){
//do something
};
return self;
}
What is the equivalent way of achieving this behavior in Java? declaring a static variable/ method?

Related

access singleton and inner classes each other in javascript

I'm kind of new to javascript. I'm so confused that javascript Objects!!
My code skeleton is bellow...
var jCanvas = new function(){
this.init = function(canvasID){
...
};
var DrawingManager = new function(){
drawInfos = []; // DrawInfo objects will be pushed into this
this.mouseState = MouseState.released;
...
};
function DrawInfo(bm, cl, id, x, y){
...
}
function Point(x, y){
...
}
var MouseState = new function(){
...
};
var Color = new function(){
...
};
var BrushMode = new function(){
...
};
};
I want jCanvas to be singleton class Object.
in jCanvas object, there are many singleton classes such as DrawingManager, MouseState, Color, BrushMode. And 2 more classes which are not singleton classes(Point, DrawInfo)
What I want is that, in DrawingManager, I want to access other classes and singleton class objects.
Problem is browser gives error that "MouseState is undefined".
I think I'm too familiar with Java, C# etc... I want my program to have good structure but this javascript make me so confused and don't know how to make good design pattern..
Please help me out..
To declare functions, don't use the new keyword. Only use it when creating instances of objects.
In JavaScript, you can declare a "class" like this (the body of the function is the constructor):
function MyClass (arg1) {
this.myClassProperty = arg1;
}
And then instantiate it:
var myObj = new MyClass();
If you want to create a singleton, the best method is to use an immediately invoked function:
var MySingleton = (function() {
var myPrivateFunction = function() { ... };
var myExportedFunction = function() { ... };
var myPrivateVar = 5;
return {
myExportedFunction: myExportedFunction
};
})();
Here, you create an anonymous function and immediately run it. It is kind of a more advanced concept though.
Or you can simply create an object:
var MySingleton = {
myProperty: 1,
myFunction: function() { ... },
...
};
Singleton classes in JavaScript make no sense. Either make a constructor ("class" for Java people) to instantiate multiple objects, or make an object. There is no point in making a constructor that you will only ever use once, then have the code to sanity-check whether or not you actually do use it only once. Just make an object.
The reason for the error is probably (but I might be wrong, I'm guessing about the rest of your code) the misunderstanding between var x = function ... and function name() ... forms. To whit:
var a = function() { console.log("a"); }
function b() { console.log("b"); }
a(); // a
b(); // b
c(); // c
d(); // TypeError: d is not a function
function c() { console.log("c"); }
var d = function() { console.log("d"); }
They are identical in effect, but they differ in whether they are hoisted to the top of the scope or not. var d is hoisted, just like function c() { ... } - so the variable d will exist, but will be undefined, since the assignment is not hoisted. Having both styles of function declarations is inconsistent unless you have a good reason for it; pick one of them and stick to it, is what I'd recommend.

How do I call a js prototype method from within the constructor function?

I've read the similar questions on SO and can't figure out what I'm doing wrong. I can't call the prototype method from within the constructor method.
I get: Uncaught TypeError: Object # has no method 'afterLoad'
var FiltersByDivision = function () {
$(document).on('afterLoad', this.afterLoad());
};
FiltersByDivision.prototype.afterLoad = function (){
console.log('afterLoad');
}
function OpenOrders() {
Widget.call(this);
FiltersByDivision.call(this);
this.widgetEndpoint = '/xxxxx';
}
OpenOrders.prototype = Object.create(Widget.prototype);
OpenOrders.prototype.constructor = OpenOrders;
There are a number of problems with this code:
You aren't inheriting from FiltersByDivision so thus an OpenOrders object does not have any FiltersByDivision methods. That's the reason why there is no afterLoad method.
$(document).on('afterLoad', this.afterLoad()); will execute this.afterLoad() immediately and pass it's return result as the event handler (which is not what you want). After you fix item 1, perhaps, you want $(document).on('afterLoad', this.afterLoad.bind(this));
There are many possible structures here. If FiltersByDivision is a separate object, then perhaps OpenOrders should just have one of those objects in its instance data like this (though if all it is doing is setting up an event handler, I'm not sure why it is a separate type of object):
var FiltersByDivision = function () {
$(document).on('afterLoad', this.afterLoad.bind(this));
};
FiltersByDivision.prototype.afterLoad = function (){
console.log('afterLoad');
}
function OpenOrders() {
Widget.call(this);
this.filter = new FiltersByDivision();
this.widgetEndpoint = '/xxxxx';
}
OpenOrders.prototype = Object.create(Widget.prototype);
OpenOrders.prototype.constructor = OpenOrders;
As jsfriend already pointed out is that afterLoad is not on ObjectOrders prototype. Doing a OtherConstructor.call does not inherit that constuctors prototype but initializes instance variables.
The value of this is the invoking object so the declaration of the function doesn't define its value but how you invoke it. You could use closures:
var FiltersByDivision = function ()
var me = this;
$(document).on('afterLoad', function(){
me.afterLoad();
});
};
More info on this, prototype and closures can be found here: https://stackoverflow.com/a/16063711/1641941

calling a function from a different context using javascript?

Im trying to call a function/Method in javscript using OOP style but from a different context.
for example:
var SomeClass = function(){
this.init = function(){
var something = "An Interesting Variable";
this.foo(something); //this works fine
},
this.foo = function(bar){
alert(bar);
}
this.foo2 = function(){
this.foo(something); // this deos not work/ something is not defined
}
};
var newClass = new SomeClass();
newClass.init();
newClass.foo2();
so basically i want to call this.foo() function within the this.foo2() context, but acting as the this.init(), im not sure this makes sense, but im new to OOP in javascript.
Your context is right, but you're trying to access a variable that isn't defined in that scope. The variable something, declared with var within init will only live inside that function.
You need to make it a member of SomeClass:
this.init = function() {
this.something = 'An interesting variable';
this.foo(this.something);
},
this.foo2 = function() {
this.foo(this.something);
}

Create a single object

I want to create a single object. Does the below code make sense?
singleObj = new function () {
// act as a constructor.
};
Am I hurting any good practice?
I need a constructor. A simple object literal would not be useful here.
If you want just a single object, in that you are never going to make one again, an object literal works perfectly here.
var x = { };
Will give you an object.
In order for
var F = function() {
};
to give you an object you will need to invoke F
var x = new F();
you could try someting like:
var objCreate = function() {
var obj = {};
// do constructor logic
return obj;
};
Just create a new object and then populate it. You don't need a contrustor to do this.
var singleObject = {};
singleObject.value1 = "whatever";
If you really want to use a function, then you need to actually call it.
var singleObj = new (function () {
// act as a constructor.
})();
We can use a self executing function by creating a anonymous function function(){}, and immediately calling it with an empty argument set.
http://www.w3schools.com/js/js_objects.asp
//Used to create an object
personObj=new Object();
personObj.firstname="John";
personObj.lastname="Doe";
personObj.age=50;
personObj.eyecolor="blue";
//Used as a constructor for the object
function person(firstname,lastname,age,eyecolor)
{
this.firstname=firstname;
this.lastname=lastname;
this.age=age;
this.eyecolor=eyecolor;
}
//how to declare objects via constructor template
var myFather=new person("John","Doe",50,"blue");
var myMother=new person("Sally","Rally",48,"green");

javascript new self invoking function

I've got a question about self invoking functions in javascript.
What I'm doing is something similar to the following
myNamespace = {}; //namespace for holding any objects/functions
//helpModule as an example
myNamespace.HelpModule = new (function(){
this.abc = '123';
//lots of other code in here...
})();
now I'm able to access properties of myNamespace.HelpModule like so:
alert(myNamespace.HelpModule.abc);
But for starters jsLint doesn't like that saying "Weird construction. Delete 'new'.",
And this page states that you shouldn't use Function Constructor, although in this case I'm not sure if its using the Function Constructor since its a self invoking function?
Anyway, it seems to work fine, and the reason I'm using it is to have "this" scope to the function instead of the global object (window). I could just defining it as an object literal or do something similar to
myNamespace.HelpModule = (function(){
var obj = {};
obj.abc = '123';
return obj;
}();
but neither of these seem as "elegant" to me.
I'm wondering if this is bad form/practice?
It is weird because the purpose of defining a constructor is to be able to reuse it to create many objects.
For your purpose, you can use this construct-
myNamespace.HelpModule = (function(){
//private stuff here
var a = 100;
return {
//public stuff here
b : 200,
something: function() {
return a + this.b;
}
};
})();

Categories

Resources