I have a class
function A()
{
var that = this;
var b = new B();
this.setBSize = function(newSize)
{
b.setSize(newSize);
}
};
function B()
{
var that = this;
this.setSize = function(newSize)
{
...
}
}
a = new A();
a.setBSize(5);
How do I avoid writing the setBSize method? How do I expose the public methods of b automatically? I want to do the call like this
a.setSize(5);
Also I need a reference to new B(); which is b inside A()
You could always set the prototype of A to B if you want to inherit all the methods in B
function A() {
var that = this;
};
function B() {
var that = this;
this.setSize = function (newSize) {
console.log(newSize); // 5
}
}
A.prototype = new B();
a = new A();
a.setSize(5);
FIDDLE
In jQuery: $.extend(that, new B());
In angular: angular.extend(that, new B());
function A()
{
var that = this;
$.extend(that, new B());
};
function B()
{
var that = this;
this.setSize = function(newSize)
{
...
}
}
a = new A();
a.setSize(5);
And if you want to use any private variables in B() class define them as var someVar, and all public (overridable) variables as that.somePublicVar
You can use call method for this:
function A() {
var that = this;
B.call(this);
};
function B() {
var that = this;
this.setSize = function (newSize) {
this.size = newSize;
}
}
var a = new A();
a.setSize(5);
Basically you invoke B in context of A, and what happens is that all own properties of the B instance are going to be assigned to this which is A instance. This pattern is called constructor or methods borrowing.
You should utilize prototyping.
make a constructor which shares the function among all the classes(objects):
var myConstructor = function(newSize){
this.setSize = function(newSize)
{
...
}
}
Now you do instanciation:
var a = new myConstructor(someSize);
var b = new myConstrucotr(someSize);
Now with this change a.setSize() is the same as b.setSize()
Using prototype for inheriting the method setSize and discarding all the this and that code.
function B() {
};
function A() {
B.call(this);
};
B.prototype.setSize = function(newSize) {
console.log(newSize);
}
A.prototype = Object.create(B.prototype);
A.prototype.constructor = A;
var a = new A();
a.setSize(5); // 5
console.log(a instanceof A);// true
console.log(a instanceof B);// true
Related
Given an object like this:
var MyObj = {
bar: 10,
foo: function() {
alert(MyObj.bar);
}
}
How can I generically reference MyObj from MyObj.foo such that if I were to change var MyObj to var MyObj2 I wouldn't need to modify the foo function?
If you want to treat MyObj like a class, you could do something like what lumio suggested, or you could do something like
function MyObj(){
this.bar = 10;
this.foo = function(){
return this.bar;
}
}
var a = new MyObj();
var b = new MyObj();
b.bar = 5;
console.log(a.foo(), b.foo()) // 10 5
If instead, you just want to reference the object's bar value, then you could just replace the alert(MyObj.bar); with alert(this.bar);
Classes would help you a lot here. In ES5 classes can be created like so:
function MyObj() {
this.bar = 10;
}
MyObj.prototype.foo = function() {
console.log( this.bar );
}
var objInstance = new MyObj;
objInstance.foo();
var objInstance2 = new MyObj;
objInstance2.bar = 20;
objInstance2.foo();
ES6 allows an even better notation:
class MyObj {
constructor() {
this.bar = 10;
}
foo() {
console.log( this.bar );
}
}
var objInstance = new MyObj;
objInstance.foo();
var objInstance2 = new MyObj;
objInstance2.bar = 20;
objInstance2.foo();
Use babel to convert it to ES5.
I am trying to inherit the members from test1 into test2 but it does not work.
function inherit(a, b)
{
// none of these work
//a.prototype = b;
//a.prototype = b();
//a.prototype = new b();
//a.prototype = Object.create(b.prototype);
//a.prototype = Object.create(b);
//a.prototype = b.prototype;
}
function test1()
{
this.val1 = 123;
}
function test2()
{
this.val2 = 456;
}
var testInstance = new test2();
inherit(testInstance, test1);
console.log(testInstance.val1);
How can I make test2 inherit the members of test1?
var A = function () {
this.p1 = 2;
};
A.prototype.f1 = function () {
return 7;
};
var B = function () {
inherit(A, B);
};
function inherit(Child, Parent) {
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;
}
var b = new B();
console.log(b.p1); // get undefined here
I am new to JS, sorry for dump question. I would like to inherit B from A. What am I doing wrong?
You're only calling inherit() after creating the instance of B.
You need to call inherit() statically, once, after defining both functions.
You also need to call A on your instance in B.
For more details on how to properly do inheritance, see my blog.
What am I doing wrong?
Two things:
You're calling inherit inside B. You should be doing it outside.
Inside B, you should be calling A, e.g.
A.call(this/*, other, args, here, if, needed*/);
or
A.apply(this, arguments);
to pass on all of the arguments B received at runtime via the automatic arguments pseudo-array.
Like so:
var A = function () {
this.p1 = 2;
};
A.prototype.f1 = function () {
return 7;
};
var B = function () {
A.call(this); // <==== Added
};
inherit(A, B); // <==== Moved
function inherit(Child, Parent) {
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;
}
var b = new B();
console.log(b.p1); // get 2 here now
You didn't call the base constructor. Also, it's enough if you inherit only once the classes.
var A = function () {
this.p1 = 2;
};
A.prototype.f1 = function () {
return 7;
};
var B = function () {
A.apply(this, arguments);
};
inherit(A, B);
function inherit(Child, Parent) {
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;
}
var b = new B();
console.log(b.p1); // get undefined here
I am trying to get subclass to access parent variable. Can someone tell me what's wrong with this code?
function a() {
this.val = 600;
var self = this;
this.c = new b();
this.d = function() {
console.log("P:");
this.c.p();
}
}
function b() {
this.val2 = 1;
this.p = function() {
console.log(self.val);
}
}
var test = new a();
test.d();
In the b function, self is undefined since it doesn't create a closure. This means you can't reference self.
The way you coded it doesn't create closures.
If you do it like this it works:
http://jsfiddle.net/y2A93/
function a() {
this.val = 600;
var self = this;
this.c = new b();
this.c.self = self; // create `self` variable
this.d = function() {
console.log("P:");
this.c.p();
}
}
function b() {
this.val2 = 1;
this.p = function() {
console.log(this.self.val); // create closure that passes `self` from `b` to `p`.
}
}
var test = new a();
test.d();
What I do is create a self variable in the instance of b called c. Than I create a closure by accessing the self in b from an inner function; p in this case.
Error: self does not exist in the scope of function b. self exists only in scope of a. Try assigning this.c.parent = self (or constructing this.c with that value) and access it from
(new b()).p() as this.parent instead
Try:
function a() {
this.val = 600;
var self = this;
this.c = new b(self);
this.d = function() {
console.log("P:");
this.c.p();
}
}
function b(parent) {
this.val2 = 1;
this.parent = parent;
this.p = function() {
console.log(this.parent.val);
}
}
var test = new a();
test.d();
is there a way to get the actual called function used to instance the object?
function A(){}
A.prototype.test = function(){};
function B(){}
B.prototype = Object.create(A.prototype);
B.prototype.test = function(){};
var x = new B();
alert(x.constructor); // alerts "A"
i'm also interested in cross browser support
thanks
After this sort of inheritance, you need to explicitly set the constructor of the 'subclass'.
...
B.prototype = Object.create(A.prototype);
B.prototype.constructor = B;
...
As far as I'm aware, there is no way to do this automatically. Even Google's Closure library has something like this;
var inherit = function(subClass, superClass) {
var temp = function() {};
temp.prototype = superClass.prototype;
subClass._super = superClass.prototype;
subClass.prototype = new temp();
subClass.prototype.constructor = subClass;
};
So, if you have a constructor with arguments, you can simply do something like
var ParentClass = function(arg1, arg2) {
this.arg1 = arg1;
this.arg2 = arg2;
};
ParentClass.prototype.show = function() {
console.log('Parent!');
console.log('arg1: ' + this.arg1);
console.log('arg2: ' + this.arg2);
};
var ChildClass = function(arg1, arg2, arg3) {
ParentClass.call(this, arg1, arg2);
this.arg3 = arg3;
};
inherit(ChildClass, ParentClass);
ChildClass.prototype.show = function() {
console.log('Child!');
console.log('arg1: ' + this.arg1);
console.log('arg2: ' + this.arg2);
console.log('arg3: ' + this.arg3);
};
Example.