I found a Module pattern in JS:
<script>
var MODULENAME = (function(my, $) {
my.publicVar = "5";
my.publicFn = function() {};
return my;
}(MODULENAME || {}, jQuery));
</script>
However I cannot perform instantiation. Does the module pattern allow for that?
Instantiantion means basically that you'll run a function using new.
So maybe you're looking for this?
var Some = function (param) {
var somePrivateVar = 'private';
this.somePublicVar = 'public';
this.method = function () {
return param;
};
};
var some = new Some('abla');
console.log(some.method());
// some.somePrivateVar === undefined
// some.somePublicVar === 'public'
In your case MODULENAME is an object (object, not a function) with publicVar and publicFn. It's not meant to be instantiated the same way you wouldn't call new jQuery().
Your module object can contain anything. Perhaps you're looking for including a constructor in it:
var MODULENAME = (function(my, $) {
var privateVar = 10;
my.SomeConstructor = function() {
this.publicVar = 5;
}
my.SomeConstructor.prototype.someMethod = function() {};
my.SomeConstructor.prototype.getPrivate = function() { return 10; };
return my;
}(MODULENAME || {}, jQuery));
var instance = new MODULENAME.SomeConstructor();
instance.publicVar; // 5
instance.privateVar; // undefined
instance.getPrivate(); // 10
You can do this also with prototype Inheritance :
var MyClass = function(name)
{
//sharing name within the whole class
this.name = name;
}
MyClass.prototype.getName = function(){
return this.name;//now name is visible to getName method too
}
MyClass.StaticMethod = function()
{
console.log("Im Static");
// and since is not in prototype chain, this.name is not visible
}
var myclass = new MyClass("Carlos");
console.log(myclass.getName())//print "Carlos"
MyClass.StaticMethod()// print "Im Static"
myclass.StaticMethod() // error
Se all this article
Related
My function gets model name as string, I need to create new instance of object based on its name.
ex.:
modelName = 'MockA';
model = new modelName();
this is ofcourse not working. in php i would use
model = new $$modelName
thanks in advance
If MockA is in global scope you can use:
var model = new window[modelName]();
if not then you should reconsider the way you store your models, eg. with an object of models:
var my_models = {
MockA: function() {},
MockB: function() {}
}
and to access
var MockA = my_models.MockA;
// or
var model_name = 'MockA';
var MockA = my_models[model_name];
You can use an object factory or bracket notation.
Sample of code:
// First example: Use a Factory
var MockA = function() {
this.sayHello = function() {
console.log('Hi from MockA ');
};
},
MockB = function() {
this.sayHello = function() {
console.log('Hi from MockB ');
}
},
factory = function(type) {
var obj;
switch (type) {
case 'MockA':
obj = new MockA();
break;
case 'MockB':
obj = new MockB();
break;
}
return obj;
}
var objA = factory('MockA');
objA.sayHello();
var objB = factory('MockB');
objB.sayHello();
// Second example: Using bracket notation
var models = {
BaseMockA: {
sayHello: function() {
console.log('Hi from BaseMockA ');
}
},
BaseMockB: {
sayHello: function() {
console.log('Hi from BaseMockB ');
}
}
};
var baseObjA = Object.create(models['BaseMockA']);
baseObjA.sayHello();
var baseObjB = Object.create(models['BaseMockB']);
baseObjB.sayHello();
We are using a oop architecture as the following, and we have a scope problem. We have the 'self' variable for saving the context, but when we call the function 'print' in the overridden class, we are using the 'self' variable instead of 'this', and we cannot override a base method.
Do someone knows how override this methods with this architecture?
var baseItem = function() {
var self = {};
self.a = function () {
console.log('base');
return 1;
};
self.print = function() {
return self.a();
}
return self;
};
var middleItem = function () {
var parent = baseItem();
var self = Object.create(parent);
return self;
}
var overrided = function () {
var parent = middleItem();
var self = Object.create(parent);
self.a = function() {
console.log('overrided');
return 55;
};
return self;
}
var obj = overrided();
overrided.print(); // This returns 1 instead 55, as we would want
I have some classes that share identical methods and are distinguished only by a few static (aka class) variables. My thought is to put the common methods into a base class that accesses the static variables.
Here is a solution that works, but it seems like a real cough kludge. Is there a better / more idiomatic way to do this?
"use strict";
// common code
function Base() { }
Base.prototype.f1 = function() {
console.log(Object.getPrototypeOf(this).constructor.VAR1); // this feels really really wrong!
}
Base.prototype.f2 = function() {
console.log(Object.getPrototypeOf(this).constructor.VAR2); // ditto
}
// specialization A
function SubA() { Base.call(this); }
SubA.prototype = Object.create(Base.prototype);
SubA.prototype.constructor = SubA;
SubA.VAR1 = "suba v1";
SubA.VAR2 = "suba v2";
// specialization B
function SubB() { Base.call(this); }
SubB.prototype = Object.create(Base.prototype);
SubB.prototype.constructor = SubB;
SubB.VAR1 = "subb v1";
SubB.VAR2 = "subb v2";
This works as expected:
> var a = new SubA();
> var b = new SubB();
> a.f1()
suba v1
undefined
> b.f2()
subb v2
undefined
an alternative
Of course I could write methods to encapsulate the differences between SubA and SubB. The syntax is less tortured, but it still feels wrong to write methods that are essentially behaving like static variables:
"use strict";
function Base() { }
Base.prototype.f1 = function() {
console.log(this.getVar1());
}
Base.prototype.f2 = function() {
console.log(this.getVar2());
}
function SubA() { Base.call(this); }
SubA.prototype = Object.create(Base.prototype);
SubA.prototype.constructor = SubA;
SubA.prototype.getVar1 = function() { return 'suba v1'; }
SubA.prototype.getVar2 = function() { return 'suba v2'; }
function SubB() { Base.call(this); }
SubB.prototype = Object.create(Base.prototype);
SubB.prototype.constructor = SubB;
SubB.prototype.getVar1 = function() { return 'subb v1'; }
SubB.prototype.getVar2 = function() { return 'subb v2'; }
> var a = new SubA();
> var b = new SubB();
> a.f1()
suba v1
undefined
> b.f2()
subb v2
undefined
Is there a particular reason to put VAR1 and VAR2 in the class objects themselves rather than in their prototypes? If not, things become much simpler:
function Base() { }
Base.prototype.f1 = function() {
console.log(this.VAR1);
};
Base.prototype.f2 = function() {
console.log(this.VAR2);
};
// specialization A
function SubA() { Base.call(this); }
SubA.prototype = Object.create(Base.prototype);
SubA.prototype.constructor = SubA;
SubA.prototype.VAR1 = "suba v1";
SubA.prototype.VAR2 = "suba v2";
// specialization B
function SubB() { Base.call(this); }
SubB.prototype = Object.create(Base.prototype);
SubB.prototype.constructor = SubB;
SubB.prototype.VAR1 = "subb v1";
SubB.prototype.VAR2 = "subb v2";
The above code passes your tests.
I have a 'model' class/prototype defined as below, it has subclass named 'given' which tries to access method 'getNodes()' of model class.
But it gives exception for 'this.getNodes' saying undefined.
var model = {
constructor: function(/*string*/ mode, /*string*/ name, /*object*/ properties) {
this._mode = mode;
this.beginX = 100;
this.beginY = 100;
this.nodeWidth = 200;
this.nodeHeight = 200;
this.x = this.beginX;
this.y = this.beginY;
this.lastNodeVisible = null;
this.ID = 1;
this.taskName = name;
this.properties = properties;
this.checkedNodes = new Array();
// this.model = #call_build_method;
/*
add subclasses with model accessors
*/
this.given = {
getNodes: this.getNodes,
setNodeName: this.setNodeName
};
},
getNodes: function() {
// Summary: returns an array containing the nodes in the given model
return #someobject;
},
}
I assume that you want to call a method in the parent class with the correct scope.
Here are two ways to do this, one using dojo hitch, and one without:
require([
"dojo/_base/lang"
],function(lang){
model = function(){
var obj = {
data: "ok",
getData4: function(){
return this.data;
}
};
obj.sub = {
getData5: lang.hitch(obj, obj.getData4),
getData6: function(){return obj.getData4.apply(obj,arguments);}
};
return obj;
};
m = new model();
console.log("call getData4: ", m.getData4()); // returns "ok"
console.log("call getData5: ", m.sub.getData5()); // returns "ok"
console.log("call getData6: ", m.sub.getData6()); // returns "ok"
});
You need to store this in variable in outter scope:
this.model = <SOMETHING>;
var self = this;
this.given = {
getNodes: function(){self.getNodes(self.model);}
// inside a function this is this.given
};
I have JavaScript variable as a literal:
var global = {
getTime : function() {
var currentDate = new Date();
return currentDate.getTime();
}
};
And I wish to extend this literals with other different functions, which are going to be created as variables:
var doSomething = function(param){
$("#" + param).hide();
return "hidden";
}
How can I extend my literal with a new variable, which holds a function?!At the end I wish to use this in such a way:
alert( global.doSomething("element_id") );
To extend your global variable with the method doSomething, you should just do this:
global.doSomething = doSomething;
http://jsfiddle.net/nslr/nADQW/
var global = {
dothis: function() {
alert('this');
}
}
var that = function() {
alert('that');
};
var global2 = {
doSomething: that
};
$.extend(global, global2);
$('#test').click(function() {
global.doSomething();
});
global.doSomething = function(param){
or
var doSomething = function(param){ ...
global.doSomething = doSomething;