inheritance namespace javascript - javascript

How can I inherit an objects variables within namespace(scope)?
var f2 = {
a: 'test'
}
f2.history = {
load: function(){ alert(this.a); }
}
// Turns out Undefined
f2.history.load();

There is no link between f2.history and f2. More generally there is no link between a property value and its holder.
You could call it like this :
f2.history.load.call(f2);
Or you could declare your objects with a factory :
var f2 = (function(){
var self = {
a: 'test'
};
self.history = {
load: function(){ alert(self.a); }
};
return self;
})();
This would allow
f2.history.load();
Another variant would let you define the submodules in a more separated way :
var f2 = {
a: 'test'
};
(function(f){
f.history = {
load: function(){ alert(f.a); }
}
})(f2);
The advantage of this last construct is that it's easy to declare sub-modules in different files.

use the namespace, f2, not this.
load: function(){ alert(f2.a); }
works
var f2 = {
a : 'test',
init: function(a) {
if (a) this.a = a; //set a, if a is defined
},
};
function history(a) {
function F() {};
F.prototype = f2;
var f = new F();
f.init(a);
load = function() {
alert(f.a);
}
return this;
}
var h1 = history();
h1.load(); //alerts "test"
var h2 = history('history');
h2.load(); //alerts "history"
//but now h1 also holds history
h1.load();

Related

Javascript: Run a function defined outside this closure as if it were defined inside this closure

I want to have a function A that accepts another function B as an argument, and then runs B as it were defined within the closure scope of A, i.e. has access to all the local variables.
For example, simplistically:
var A = function(B){
var localC = "hi";
B();
}
var B = function(){
console.log(localC);
}
A(B); // to log 'hi'
The only way I have found is to use eval. Does ec6 give any better options maybe?
One solution is to pass localC as argument in function B:
var A = function(B) {
var localC = "hi";
B(localC);
}
var B = function(localC) {
console.log(localC);
}
A(B); // outputs hi
Alternative using arguments:
var A = function(B) {
var localC = "hi";
B(localC, "test");
}
var B = function() {
var i = 0;
for (i; i < arguments.length; i++) {
console.log(arguments[i]);
}
}
A(B); // outputs hi, test
You can make the context explicit and pass it to B:
var A = function(B){
var context = {
localC: "hi"
};
B(context);
}
var B = function(context){
console.log(context.localC);
}
A(B); // hi
You can also use this with new and prototype:
var A = function() {
this.localC = "hi";
}
A.prototype.b = function(context){
console.log(this.localC);
}
var a = new A();
a.b(); // hi
or without the prototype:
var A = function() {
this.localC = "hi";
}
var a = new A();
a.b = function(context){
console.log(this.localC);
};
a.b(); // hi
You can use this with bind:
var a = {
localC: "hi"
};
function B(foo) {
console.log(this.localC, foo);
}
B.bind(a)("foo"); // hi foo
// .call:
B.call(a, "foo"); // hi foo
bind sets the context for this. call takes the context as it's first argument.
This one is not good:
var A = function(B){
var localC = "hi";
B.bind(this)(); // this is the global object, you need `new` to create a new scope
}
var B = function(){
console.log(this.localC);
}
A(B); // undefined
var A = function(B){
var self = this;
self.localC = "hi";
self.localD = "hello";
B();
};
var B = function(){
var self=this;
alert(self.localD);
}
A(B); // to log 'hi'

Javascript Object-Oriented-Programming

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

How to add methods to an instance of the object

For example I have an instance of some object:
A = function(){};
a = new A();
How to add methods
{b: function(){ console.log('b') },
c: function(){ console.log('c') }
}
to instance a?
If you want to add methods to an instance, just add them:
a.methodA = function() {
alert("method A");
};
You can do this with any object. However, you can also add them to the prototype of an instance and this will allow the same methods to be visible on all other instances:
var a = new A(),
b = new A();
a.prototype.methodA = function() {
alert("method A");
};
b.methodA();
If you want to add multiple methods in one go, create a mix function or use a framework:
function mix(a, b, typ) {
var n, o;
for (n in b) {
if (! b.hasOwnProperty(n)) continue;
if (!!(o = b[[n]) && (! typ || typeof o === typ)) {
a[n] = o;
}
}
}
Then...
var a = new A();
mix(a, {
"methodA": function() {
alert("method A");
},
"methodB": function() {
alert("method B");
}
}, "function");
You should have a look at prototype.
Here is a good explanation about it.
Edit: You can also set the prototype to an array of functions, like that:
var Person = new function() {};
methods = {
"methodA": function() {alert("method A")},
"methodB": function() {alert("method B")},
}
Person.prototype = methods
p = new Person()
p.methodA(); // Alerts "method A"
Prototype is used to add methods to ALL instances of a certain type of object (useful for memory management). If you just want to add methods to only one instance of an object you add them just as you would any property:
var A = function() {
//......
}
var myA = new A();
myA.methodOne = function() { console.log('called methodOne on myA'); }
myA.methodTwo = function() { console.log('called methodTwo on myA'); }
myA.methodOne();
myA.methodTwo();
Check out jQuery.extend() if you're okay with using a library/framework.
A = function(){};
a = new A();
d = {b: function(){ console.log('b') },
c: function(){ console.log('c') }
};
$.extend(a, d);

js prototype class.create coexistance between variables in subclass and superclass

Very simply put, I have lots of classes that share variables and have their own variables. So I created a super class called Resource and many subclasses. The problem is that I want to be able to set and get any value. I simplified the code, but this is what i can't do. Keep in mind that there are many many variables in each class, icluding the superclass and I dont want to redefine the class each time.
var MySuperClass = Class.create({
initialize:function () {
var a;
var b;
var c;
//Getters
this.getA=function () {
return a;
};
this.getB=function () {
return b;
};
this.getC=function () {
return c;
};
//Setters
this.setA=function (val) {
a = val;
};
this.setB=function (val) {
b = val;
};
this.setC=function (val) {
c = val;
};
//end Setters
},
sub:function () {
return this.getA()-this.getB()-this.getC();
}
});
var MyClass = Class.create(MySuperClass, {
initialize:function () {
var d;
var e;
//Getters
this.getD=function () {
return d;
};
this.getE=function () {
return b;
};
this.getC=function () {
return c;
};
//Setters
this.setA=function (val) {
a = val;
};
this.setB=function (val) {
b = val;
};
this.setC=function (val) {
c = val;
};
//end Setters
},
add:function () {
return this.getA()+this.getB()+this.getC()+this.getD()+this.getE();
}
});
function test() {
myclass=new MyClass();
myclass.setA(1);
myclass.setB(0);
myclass.setC(3);
myclass.setD(2);
myclass.setE(3);
var result=myclass.add();
var result2=myclass.sub();
alert(result+' '+result2);
}
Of course the subclass is overriding the superclass initialize so the values cannot be accessed. How can I initialize subclass variables and superclass variables so that they can both be accessed from the test function?
As always, thank you for your help
You are initializing var variables , that means it will be available only inside the initialize function. Make those variable as class level variable by initializing like the following
initialize:function () {
this.a;
this.b;
this.c;
},
getA:function () {
return this.a;
}
This way all these variable will be available in base class as well as super class.

Assigning defined function to an object attribute in javascript

i have a object in javascript and some already defined functions. but how can i assign those functions to the object attributes. i tried different ways. but no hope.. the snippet is given below
// object
var func = {
a : '',
b : ''
};
// methods
var test1 = function(i) { console.log(i); }
var test2 = function(i) { console.log(i*100); }
i need to assign the test1 to a and test2 to b. i tried like this.
var func = {
a : test1(i),
b : test2(i)
};
obviously the errors i not defined is throwing.. is ther any solution other than the below give sinppet.
var func = {
a : function(i) { test1(i); },
b : function(i) { test2(i); }
};
This does what you're asking:
var test1 = function(i) { console.log(i); }
var test2 = function(i) { console.log(i*100); }
var func = {
a: test1,
b: test2
}
But isn't very good style.
This might be better:
function exampleClass () {}
exampleClass.prototype.a = function(i) { console.log(i); };
exampleClass.prototype.b = function(i) { console.log(i*100); };
var exampleObject = new exampleClass();

Categories