I want to extend the object Kinetic.Shape (from which every other shape extends) with some more properties and methods.
What I tried was
Kinetic.Util.addMethods(Kinetic.Shape, {
foo: 'bar'
});
So say if I created a new Kinetic.Circle instance, it should contain this defined property ( and every other shape should do so to).
new Kinetic.Circle(options).foo; // returns undefined
// should return 'bar'
How can I achieve this behaviour?
Waiting for merge this pull request https://github.com/ericdrowell/KineticJS/pull/497.
Now you can do this - replace Kinetic.Util.extend function with this one:
extend: function(child, parent) {
function ctor() {
this.constructor = child;
}
ctor.prototype = parent.prototype;
var old_proto = child.prototype;
child.prototype = new ctor();
for (var key in old_proto) {
if (old_proto.hasOwnProperty(key))
child.prototype[key] = old_proto[key];
}
child.__super__ = parent.prototype;
}
Related
My question is inspired from this question
This is typescript inheritance code
var __extends = (this && this.__extends) || function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
__.prototype = b.prototype;
d.prototype = new __();
};
and I simplified version to this version
function extend(Destination, Base) {
function Hook() { this.constructor = Destination; }
Hook.prototype = Base.prototype;
var hook = new Hook();
Destination.prototype = hook;
};
and I draw graphical represantation inspired from here:
Could you confirm or correct ghaphical representation?
I especially did not understand this part:
function Hook() { this.constructor = Destination; }
And could you tell me how inheritance work with arguments and accompanied example
It it's any help, I've commented each line to illustrate what it does, based on the current __extends function (it's changed slightly from your example)
var extend = function (subType, superType) {
// Copy superType's own (static) properties to subType
for (var property in superType) {
if (superType.hasOwnProperty(property)) {
subType[p] = superType[p];
}
}
// Create a constructor function and point its constructor at the subType so that when a new ctor() is created, it actually creates a new subType.
function ctor() {
this.constructor = subType;
}
if(superType === null) {
// Set the subType's prototype to a blank object.
subType.prototype = Object.create(superType);
} else {
// set the ctor's prototype to the superType's prototype (prototype chaining)
ctor.prototype = superType.prototype;
// set the subType's prototype to a new instance of ctor (which has a prototype of the superType, and whos constructor will return a new instance of the subType)
subType.prototype = new ctor();
}
};
Note that __extends may change again in the very near future to include the use of Object.setPrototypeOf(...);
GitHub - Change Class Inheritance Code
When I synthase my question and this answer and #series0ne's answer
Here is what I understand from typescript inheritance:
function ctor() does:
As in the linked answer:
Car.prototype.constructor = Car;
it is equivelant
subType.prototype.constructor = subType
which provides:
subType.constructor === subType -> true
for
ctor.prototype = superType.prototype;
subType.prototype = new ctor();
it is equivalent
Car.prototype = new Vehicle(true, true);
which ensures
subType.prototype = new superType();
I am struggling accessing a property that is set on a child object and accessing it via method on its prototype.
var Parent = function () {
this.getColor = function () {
return this.color;
};
};
var Child = function () {
this.color = red;
};
Child.prototype = new Parent;
var Test = new Child();
console.log(Test.getColor());
=> undefined
Any and all assistance is appreciated.
Here's how I'd do it
function Parent(color) {
function getColor() {
return color;
}
// export public functions
this.getColor = getColor;
}
Now for the Child
function Child(color) {
Parent.call(this, color);
}
Child.prototype = Object.create(Parent.prototype, {
constructor: {value: Child}
});
Let's see it work
var c = new Child("red");
c.getColor(); // "red";
Explanation:
The important bits of the Child constructor
Make sure to call the Parent constructor with the context of the Child instance (this)
Parent.call(this, color);
Setup the Child.prototype based off of the Parent.prototype
Child.prototype = Object.create(Parent.prototype, {
constructor: {value: Child}
});
You can see the node.js implementation of util.inherits uses a similar method.
This somewhat complicated line does two things for you. 1) It avoids invoking the parent constructor unnecessarily, 2) It sets the constructor property properly.
var c = new Child("red");
c instanceof Child; // true
c instanceof Parent; // true
c.constructor.name; // "Child"
But using your code, you would see
var c = new Child("red");
c instanceof Child; // true
c instanceof Parent; // true
c.constructor.name; // "Parent"
This may or may not be a concern for you, but depending on how you want to use your parent/child objects, it may be hard to programmatically differentiate which objects are from the Parent constructor and which ones are from the Child constructor.
Ok, let's see another way to do it by assigning the color property on the object itself
function Parent(color) {
this.color = color;
}
We'll add the getColor method directly to the Parent.prototype
Parent.prototype.getColor = function getColor() {
return this.color;
};
The Child constructor will stay the same. Keep in mind we'll use the same inheritance pattern we used above
function Child(color) {
Parent.call(this, color);
}
Child.prototype = Object.create(Parent.prototype, {
constructor: {value: Child}
});
Lastly, let's get the color using our getColor method
var c = new Child("red");
c.getColor(); // "red"
Or you could access the property on the object directly
c.color; // "red"
When should I use first notation:
var object = {
a: function() {
// object.a method body
},
b: function() {
// object.b method body
},
c: function() {
// object.c method body
},
};
and when the second one?
function Class() {};
Class.prototype.a = function() {
// object.a method body
};
Class.prototype.b = function() {
// object.b method body
};
Class.prototype.c = function() {
// object.c method body
};
var object = new Class();
The main advantage is that the functions are shared by all instances in second case, which makes the objects lighter. It explicitly defines the objects as instances of what is conceptually a class.
But the correct syntax is
function MyClass(){
}
MyClass.prototype.a = function(){
};
...
var o = new MyClass();
It also allows you to define an inheritance chain :
function OtherClass(){
}
OtherClass.prototype = new MyClass(); // makes OtherClass extend MyClass
OtherClass.prototype.b = function(){
};
...
var o2 = new OtherClass();
o2 has the functions of both OtherClass and MyClass.
The MDN gives more details in its Introduction to Object-Oriented JavaScript.
I'm currently in the process of converting a quite large actionscript library to work in a nodejs project of mine. While doing so I stumbled upon something that could be an issue: Building classes from classes.
Is there a way to use an object as the base for another object(IE: inherits all members from the base object, then overwrites same name members from the extending object)?
Right now this is what I'm doing, though it's getting a bit difficult to manage now that there are 3+ classes built one on top of another:
// The base object which others may extend
function A() {
this.a = "pie";
}
A.prototype.yum = function() {
return this.a + " is AWESOME!";
}
// The "extends A" object.
// Instead of creating an instance of "B", I current just create an instance of "A",
// then adding the members from "B" to it at which point I return the "A" instance.
function B() {
var a = new A();
a.b = "pie";
// Notice how I have to declare the overwriting function here instead of being able
// to drop it into B's prototype. The reason this bothers me is instead of just
// having one copy of the function(s) stored, each time a "new B" is created the
// function is duplicated... for 100s of "B" objects created, that seems like poor
// memory management
a.yum = function () {
return "I like " + this.a + " and " + this.b;
};
return a;
}
console.log((B()).yum());
Is it possible to do something along the following?
I know this isn't valid, but it gives the idea.
function A(){
this.a = "pie"
}
A.prototype.yum = function () {
return this.a + " is AWESOME!";
}
function B(){
// Throws an "illegal left hand assignment" Exception due to overwriting `this`;
this = new A();
this.b = "cake"
}
B.prototype.yum = function () {
return "I like "+this.a+" and "+this.b;
}
console.log((new B()).yum());
Notes:
1: I know javascript doesn't have classes; it uses objects and prototypes. Otherwise I wouldn't be asking.
2: This isn't the actual code im (trying) to convert; it's a generalized example
3: Please do not suggest a library. I know at times they are valuable, but I'd rather not have to maintain, depend on and include an entire library for the project.
ANSWER:
I know it's bad form to alter native member prototypes, but I think this merits it, due to the lack of possible functionality, and the size of it.
Object.prototype.extendsUpon = function (p) {
var h = Object.prototype.hasOwnProperty;
for(var k in p)if(h.call(p,k))this[k]=p[k];
function c(c){this.constructor=c;}
c.prototype = p.prototype;
this.prototype = new c(this);
this.__base__ = p.prototype;
}
function object_Constructor_built_ontop_of_another_constructor() {
this.extendsUpon(base_Object_to_built_atop_off);
this.__base__.constructor.apply(this, arguments);
// From here proceed as usual
/* To access members from the base object that have been over written,
* use "this.__base__.MEMBER.apply(this, arguments)" */
}
Very much possible. You can do it in multiple ways, the more complete is used in coffeescript:
var ClassBase, ClassTop,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
ClassBase = (function() {
function ClassBase() {}
return ClassBase;
})();
ClassTop = (function(_super) {
__extends(ClassTop, _super);
function ClassTop() {
return ClassTop.__super__.constructor.apply(this, arguments);
}
return ClassTop;
})(ClassBase);
There is going to be some boilerplate code. ClassTop is inheriting everything from ClassBase. The classes don't have much inside them other then an __extend, a (function(_super... and some constructor boilerplate but it's fairly simple.
The inheritance is mostly managed by the __extends boilerplate that does some magic. The full __extends method is beautified here:
__extends = function (child, parent) {
for (var key in parent) {
if (__hasProp.call(parent, key)) child[key] = parent[key];
}
function ctor() {
this.constructor = child;
}
ctor.prototype = parent.prototype;
child.prototype = new ctor();
child.__super__ = parent.prototype;
return child;
};
Again, much less scary then before. You're basically checking properties that the parent has and applying them to the child. More information can be found here: http://www.jimmycuadra.com/posts/coffeescript-classes-under-the-hood
I'm not very well aquainted with javascript inheritance, and I'm trying to make one object inherit from another, and define its own methods:
function Foo() {}
Foo.prototype = {
getColor: function () {return this.color;},
};
function FooB() {}
FooB.prototype = new Foo();
FooB.prototype = {
/* other methods here */
};
var x = new FooB().getColor();
However, the second one overwrites the first one(FooB.prototype = new Foo() is cancelled out). Is there any way to fix this problem, or am I going in the wrong direction?
Thanks in advance, sorry for any bad terminology.
Each object can only have one prototype, so if you want to add to the prototype after inheriting (copying) it, you have to expand it instead of assigning a new prototype. Example:
function Foo() {}
Foo.prototype = {
x: function(){ alert('x'); },
y: function(){ alert('y'); }
};
function Foo2() {}
Foo2.prototype = new Foo();
Foo2.prototype.z = function() { alert('z'); };
var a = new Foo();
a.x();
a.y();
var b = new Foo2();
b.x();
b.y();
b.z();
One solution would be:
function FooB() {}
var p = new Foo();
p.methodA = function(){...}
p.methodB = function(){...}
p.methodC = function(){...}
...
FooB.prototype = p;
Update: Regarding expanding with an existing object. You can always copy the existing properties of one object to another one:
FooB.prototype = new Foo();
var proto = {
/*...*/
};
for(var prop in proto) {
FooB.prototype[prop] = proto[prop];
}
As long as proto is a "plain" object (i.e. that does not inherit from another object) it is fine. Otherwise you might want to add if(proto.hasOwnProperty(prop)) to only add non-inherited properties.
You can use an extend function which copies the new members to the prototype object.
function FooB() {}
FooB.prototype = new FooA();
extend(FooB.prototype, {
/* other methods here */
});
extend
/**
* Copies members from an object to another object.
* #param {Object} target the object to be copied onto
* #param {Object} source the object to copy from
* #param {Boolean} deep whether the copy is deep or shallow
*/
function extend(target, source, deep) {
for (var i in source) {
if (deep || Object.hasOwnProperty.call(source, i)) {
target[i] = source[i];
}
}
return target;
}