how to get the actual constructor of a javascript object? - javascript

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.

Related

How to write a singleton class in javascript using IIFE module pattern?

How to write a singleton class in javascript using IIFE module pattern ?
Can you plz provide an example?
I tried something like this, but it fails for x2.getInstance.
As per my understanding, x2.getInstance() should get the same instance as x1.getInstance(). How can I achieve this using IIFE module pattern ??
var x = (function(){
var instance ;
var vconstructor = function(){};
//vconstructor.prototype.method1 = function(){}
//vconstructor.prototype.method2 = function(){}
vconstructor.prototype.getInstance = function(){
if (!instance) {
console.log('critical section');
instance = somefunc();
return instance;
}
};
function somefunc(){
return { "key1": "value1"};
}
return vconstructor;
})();
var x1 = new x();
console.log('1.');
console.log(x1 instanceof x);
console.log(x1);
console.log('2.' + x1.getInstance());
var x2 = new x();
console.log(x2);
console.log('x2: ' + x2.getInstance());
Kindly advise.
You can try this:
var Singleton = (function () {
var instance;
function createInstance() {
var object = new Object("I am the instance");
return object;
}
return {
getInstance: function () {
if (!instance) {
instance = createInstance();
}
return instance;
}
};
})();
function run() {
var instance1 = Singleton.getInstance();
var instance2 = Singleton.getInstance();
alert("Same instance? " + (instance1 === instance2));
}

JavaScript: Inheritance in ECMAScript5

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

Javascript inherited class constructor issue

I want to create a subclass from a superclass using prototypes in javascript, so I set them up:
var SuperClass = function() {
this.a = 1;
this.get = function() {return this.a;}
this.init = function() {
CreateStrangeThings();
}
this.init();
}
var SubClass = function() {
this.b = 2;
this.get = function() {return this.b;}
}
SubClass.prototype = new SuperClass();
The problem is, the line SubClass.prototype = new SuperClass(); calls the CreateStrangeThings(); function. I want this function to be called only when I create the subclass object (var subOjbect = new SubClass();)
How to overcome this issue? Maybe I should use SubClass.prototype = SuperClass; ? Is it wise?
EDIT:
SubClass.prototype = SuperClass;
removes "a" property from SubClass
The problem is, the line SubClass.prototype = new SuperClass(); calls the CreateStrangeThings(); function.
Yes. That's why that pattern, despite being often-cited, is wrong. Another reason is that it ignores the possibility the superclass constructor may require arguments.
Instead, create the prototype object without calling the super constructor:
SubClass.prototype = Object.create(SuperClass.prototype);
SubClass.prototype.constructor = SubClass;
...and also call the super constructor inside SubClass:
var SubClass = function() {
SuperClass.call(this);
this.b = 2;
this.get = function() {return this.b;}
};
So all together we get:
var SuperClass = function() {
this.a = 1;
this.get = function() {return this.a;}
this.init = function() {
CreateStrangeThings();
}
this.init();
};
var SubClass = function() {
SuperClass.call(this);
this.b = 2;
this.get = function() {return this.b;}
};
SubClass.prototype = Object.create(SuperClass.prototype);
SubClass.prototype.constructor = SubClass;
Or of course, use ES2015 and a transpiler.
class SuperClass {
constructor() {
this.a = 1;
this.get = function() {return this.a;};
this.init = function() {
CreateStrangeThings();
};
this.init();
}
}
class SubClass {
constructor() {
super();
this.b = 2;
this.get = function() {return this.b;};
}
}
How to overcome this issue? Maybe I should use SubClass.prototype = SuperClass; ? Is it wise?
No. If you want objects created via new SubClass to inherit properties from SuperClass.prototype, you need SubClass.prototype to use SuperClass.prototype as its prototype. SuperClass doesn't; the prototype of SuperClass is Function.prototype, not SubClass.prototype. (Ignore the name of the prototype property on functions; it isn't their prototype, it's the prototype new assigns to objects created via new TheFunction.)

Javascript Methods/Objects

I think I finally wrapped my head around understanding how methods, constructor functions, and objects work. Could someone please review my code, and let me know if I using the correct names and syntax? Thanks a ton!
function objectConstructor (arg1, arg2) {
this.property1 = arg1;
this.property2 = arg2;
this.methodName = functionName;
}
function functionName() {
console.log(this.property1 + ' ' + this.property2);
}
var object1 = new objectConstructor('value1','value2');
console.log(object1.property1);
console.log(object1.methodName());
Methods of Javascript classes should be defined as prototype:
var CustomObject = function (arg1, arg2) {
this.property1 = arg1;
this.property2 = arg2;
};
CustomObject.prototype.functionName = function() {
console.log(this.property1 + ' ' + this.property2);
};
var object1 = new CustomObject("value1","value2");
Everything else seems fine to me though.
Use prototype functions. Else your inner functions get copied with every instance.
function Person(firstName, lastName)
{
this.firstName = firstName;
this.lastName = lastName;
}
Person.prototype.getFullName = function()
{
return this.firstName+' '+this.lastName;
}
var person1 = new Person('foo', 'bar');
console.log(person1.getFullName());
There are many other patterns which for example prevent the pollution of the global scope or allow a more class like approach. (Object literal, Module Pattern, Self-Executing Anonymous Functions)
The same example with the module pattern:
var Person = (function()
{
var Person = function(firstName, lastName)
{
this.firstName = firstName;
this.lastName = lastName;
}
Person.prototype.getFullName = function()
{
return this.firstName+' '+this.lastName;
}
return Person;
})();
var person1 = new Person('foo', 'bar');
console.log(person1.getFullName());

Is John Resig's Javascript inheritance snippet deprecated?

I'm looking for a simple way of creating two classes, one inheriting from the other, and the child redefining one of the parent's methods, and inside the new method, calling the parent's.
For example, having a class Animal and Dog, where the Animal class defines a method makeSound() which establishes how to output a sound, which Dog then overrides in its own makeSound() method to make a "woof" sound, but while also calling Animal's makeSound() to output that woof.
I looked at John Resig's model here, but it uses the native arguments.callee property which is apparently depreciated in ECMA script 5. Does that mean I shouldn't use John Resig's code?
What would one neat, simple way of writing my animal/dog code using Javascript's prototype inheritance model?
Does that mean I shouldn't use John Resig's code?
Correct, not when you are using ES5 in strict mode. However, it can be easily adapted:
/* Simple JavaScript Inheritance for ES 5.1
* based on http://ejohn.org/blog/simple-javascript-inheritance/
* (inspired by base2 and Prototype)
* MIT Licensed.
*/
(function(global) {
"use strict";
var fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;
// The base Class implementation (does nothing)
function BaseClass(){}
// Create a new Class that inherits from this class
BaseClass.extend = function(props) {
var _super = this.prototype;
// Set up the prototype to inherit from the base class
// (but without running the init constructor)
var proto = Object.create(_super);
// Copy the properties over onto the new prototype
for (var name in props) {
// Check if we're overwriting an existing function
proto[name] = typeof props[name] === "function" &&
typeof _super[name] == "function" && fnTest.test(props[name])
? (function(name, fn){
return function() {
var tmp = this._super;
// Add a new ._super() method that is the same method
// but on the super-class
this._super = _super[name];
// The method only need to be bound temporarily, so we
// remove it when we're done executing
var ret = fn.apply(this, arguments);
this._super = tmp;
return ret;
};
})(name, props[name])
: props[name];
}
// The new constructor
var newClass = typeof proto.init === "function"
? proto.hasOwnProperty("init")
? proto.init // All construction is actually done in the init method
: function SubClass(){ _super.init.apply(this, arguments); }
: function EmptyClass(){};
// Populate our constructed prototype object
newClass.prototype = proto;
// Enforce the constructor to be what we expect
proto.constructor = newClass;
// And make this class extendable
newClass.extend = BaseClass.extend;
return newClass;
};
// export
global.Class = BaseClass;
})(this);
Prototype chain with Object.create() + assign constructor
function Shape () {
this.x = 0;
this.y = 0;
}
Shape.prototype.move = function (x, y) {
this.x += x;
this.y += y;
};
function Rectangle () {
Shape.apply(this, arguments); // super constructor w/ Rectangle configs if any
}
Rectangle.prototype = Object.create(Shape.prototype); // inherit Shape functionality
// works like Rectangle.prototype = new Shape() but WITHOUT invoking the constructor
Rectangle.prototype.constructor = Rectangle;
var rect = new Rectangle();
rect instanceof Rectangle && rect instanceof Shape // returns true
from Object.create documentation
information about the new keyword
This is something I came up with for inheritance using chaining as well as allowing _super to work.
/**
* JavaScript simple inheritance
* by Alejandro Gonzalez Sole (base on John Resig's simple inheritance script)
* MIT Licensed.
**/
(function (){
var initializing = false,
fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.* /;
function Class(){};
function inheritClass(superClass){
var self = this;
function Class(){
if (!initializing && typeof this._constructor === 'function')
this._constructor.apply(this, arguments);
}
Class.prototype = superClass.prototype;
Class.prototype._constructor = superClass;
Class.prototype.constructor = Class;
Class.extend = extendClass;
//currenlty if you inhert multiple classes it breaks
Class.inherit = inheritClass;
return Class;
};
function extendClass(prop) {
var self = this;
var _super = self.prototype;
function Class(){
if (!initializing && typeof this._constructor === 'function')
this._constructor.apply(this, arguments);
}
initializing = true;
var prototype = new self();
initializing = false;
for (var name in prop) {
prototype[name] = typeof prop[name] == "function" &&
typeof _super[name] == "function" && fnTest.test(prop[name]) ?
(function(name, fn){
return function() {
var tmp = this._super;
this._super = _super[name];
var ret = fn.apply(this, arguments);
this._super = tmp;
return ret;
};
})(name, prop[name]) : prop[name];
}
Class.prototype = prototype;
Class.prototype.constructor = Class;
Class.extend = extendClass;
Class.inherit = inheritClass;
return Class;
};
Class.extend = extendClass;
Class.inherit = inheritClass;
})();
//EXAMPLE
function Person(){
this.name = "No name";
console.log("PERSON CLASS CONSTRUCTOR")
}
Person.prototype.myMethod = function (t){
console.log("MY PERSON", t, this.name);
return -1;
}
var TestPerson = Class.inherit(Person).extend({
_constructor: function(){
this._super();
this.name = "JOhn";
console.log("TEST PERSON CONSTRUCTOR");
},
myMethod: function (t){
console.log("TEST PERSON", t, this.name);
return this._super(t)
}
});
var test = new TestPerson();
console.log(test.myMethod("BA"));
I've been testing it on my pixi wrapper https://github.com/guatedude2/pixijs-cli so far it's been working very well for me.
The only issue i've encountered with this approach is that you can only inherit once. If you run inherit again it will override the previous inheritance.
I prefer the way TypeScript generates a form of inheritance (Select Simple Inheritance from the dropdown). That one doesn't use arguments.callee, but an __extends prototype.
var __extends = this.__extends || function (d, b) {
function __() { this.constructor = d; }
__.prototype = b.prototype;
d.prototype = new __();
};
var Animal = (function () {
function Animal(name) {
this.name = name;
}
Animal.prototype.move = function (meters) {
alert(this.name + " moved " + meters + "m.");
};
return Animal;
})();
var Snake = (function (_super) {
__extends(Snake, _super);
function Snake(name) {
_super.call(this, name);
}
Snake.prototype.move = function () {
alert("Slithering...");
_super.prototype.move.call(this, 5);
};
return Snake;
})(Animal);
var Horse = (function (_super) {
__extends(Horse, _super);
function Horse(name) {
_super.call(this, name);
}
Horse.prototype.move = function () {
alert("Galloping...");
_super.prototype.move.call(this, 45);
};
return Horse;
})(Animal);
var sam = new Snake("Sammy the Python");
var tom = new Horse("Tommy the Palomino");
sam.move();
tom.move(34);

Categories

Resources