what is wrong with this piece of code of javascript inheritance? - javascript

function condition(){
this.expression = "";
this.toString = function(){
return this.expression;
}
};
function and(first, second){
this.expression = first + " and " + second;
}
function nop(){};
nop.prototype = condition.prototype;
and.prototype = new nop();
var a =new and(1,2);
console.log(a.toString());
it is expected to see "1 and 2" as output but this is what happened:
"[object Object]"

You are transfering the prototype of condition to nop's prototype. The problem is that your condition.toString is not declared in the prototype... Here:
function condition(){
this.expression = "";
};
condition.prototype.toString = function(){
return this.expression;
}
function and(first, second){
this.expression = first + " and " + second;
}
function nop(){};
nop.prototype = condition.prototype;
and.prototype = new nop();
var a =new and(1,2);
console.log(a.toString());
OR
function condition(){
this.expression = "";
this.toString = function(){
return this.expression;
}
};
function and(first, second){
this.expression = first + " and " + second;
}
function nop(){};
nop = condition;
and.prototype = new nop();
var a =new and(1,2);
console.log(a.toString());

you aren't overriding the toString method, because the constructer of condition is never called! try doing this;
condition.prototype.toString=function(){
return this.expression;
}

try passing strings into your and function, as at the moment you are trying to concatenate integers to a string var a =new and("1","2");

it should be like this
function condition(){
this.expression = "";
};
condition.prototype.toString = function(){
return this.expression;
}

Ok, so the problem here is you are mixing two inheritance patterns (http://davidshariff.com/blog/javascript-inheritance-patterns/) the pseudo-classical with the functional patterns.
You can create an object by adding methods on the constructor function:
function MyClass() {
var privateProperty = 1;
this.publicProperty = 2;
function pivateMethod() {
// some code ...
}
this.publicMethod = function() {
// some code ...
};
}
// inheritance
function SubClass() {
MyClass.call(this);
this.newMethod = function() { };
}
Here when you create a instance of this class you are creating every method again.
Then you have the prototype pattern:
function MyClass() {
this._protectedProperty = 1;
this.publicProperty = 2;
}
MyClass.prototype._protectedMethod = function() {
// some code ...
};
MyClass.prototype.publicMethod = function() {
// some code ...
};
// inheritance
function SubClass() {
MyClass.call(this);
}
SubClass.prototype = new MyClass();
SubClass.prototype.newMethod = function() { };
// OR
function SubClass() {
MyClass.call(this);
}
function dummy() { }
dummy.prototype = MyClass.prototype;
SubClass.prototype = new dummy();
SubClass.prototype.newMethod = function() { };
Yhen you must choose one of those two patterns, not both·
I've fixed your code on this fiddle: http://jsfiddle.net/dz6Ch/

Related

Javascript function does not return the right value

So i have this code:
function Class1() {
this.i = 1;
var that=this;
function nn() {
return 21;
}
this.aa = function() {
nn();
};
this.bb = function() {
this.aa();
};
this.cc = function() {
this.bb();
};
}
var o = new Class1();
var b=o.cc();
alert(b); //undefined
But when the alert is fired, I get an undefined error and not 21, Does the private method can not use a return? Thanks!
When using the function() {} syntax to define a function, you always explicitly need to return the value, i.e. not only from nn, but from all intermediate functions as well.
function Class1() {
this.i = 1;
var that = this;
function nn() {
return 21;
}
this.aa = function() {
return nn();
}
this.bb = function() {
return this.aa();
}
this.cc = function() {
return this.bb();
}
}
var o = new Class1();
var b = o.cc();
alert(b); // "21"
Apart from the answer above, the 'this' context seems weird in your functions. Maybe you are better of with arrow functions if you dont want to bind the this context to each function. I also think that it is better to actually separate private and public functions when using a 'class' like this.
function Class1() {
var _nn = function () {
return 21;
}
var _aa = function () {
return _nn();
}
var _bb = function () {
return _aa();
}
var cc = function () {
return _bb();
};
return {
cc
};
}
var o = new Class1();
var a = o.cc();
console.log(a);
Much easier to understand that it is only cc that is a public function.
So with arrow function it would instead look like this, and you can use the Class1 this context inside of your private functions without doing
var that = this; or using bind.
function Class1() {
this.privateThing = 'private';
var _nn = () => { return this.privateThing; };
var _aa = () => { return _nn(); };
var _bb = () => { return _aa(); };
var cc = () => { return _bb(); };
return {
cc
};
}

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));
}

Pure Javascript : Override functions

I would like to override some functions (for logging some informations)
I'm trying to do something like:
function universe() {
return 42;
}
universe = universe.override(function(){
console.log("Calling universe");
return this.$super();
});
Full sample:
Function.prototype.override = function (fn) {
var $super = this;
var f = function overrided() {
var context = this || $super || {};
context.$super = $super;
return fn.apply(context, arguments);
};
f.$super = $super;
return f;
};
Function.prototype.unoverride = function () {
if (this.$super) {
return this.$super;
}
return this;
};
function universe() {
return 42;
}
function mulBy10() {
console.warn("calling overrided function");
return this.$super() * 10;
}
console.log("---------");
console.log("original:", universe());
universe = universe.override(mulBy10);
console.log("new one:", universe());
universe = universe.unoverride();
console.log("reverted:", universe());
console.log("--With Object");
var MyObject = function() {
this.value = 42;
}
MyObject.prototype = {
constructor: MyObject,
getValue: function() {
return this.value;
}
};
var o1 = new MyObject();
console.log("MyObject original:", o1.getValue());
o1.getValue = o1.getValue.override(mulBy10);
console.log("MyObject new one:", o1.getValue());
o1.getValue = o1.getValue.unoverride();
console.log("MyObject reverted:", o1.getValue());
console.log("--With Object prototype");
o2 = new MyObject();
MyObject.prototype.getValue = MyObject.prototype.getValue.override(mulBy10);
console.log("MyObject.proto new one:", o2.getValue());
MyObject.prototype.getValue = MyObject.prototype.getValue.unoverride();
console.log("MyObject.proto reverted:", o2.getValue());
console.log("--With recursive");
function recur(it, max) {
console.log("it:", it, "max:", max);
if( it >= max ) {
console.log("finished");
return;
}
recur(it + 1, max);
}
recur = recur.override(function(it, max){
console.warn("Overrided recur");
return this.$super(it, max);
});
recur(0, 4);
This works fine with function, object functions.
But it doesn't work when i try to override CasperJs "require" function.
I did:
require = require.override(function(file){
console.log("require(" + file + ")");
return this.$super(file);
});
So i was wondering, in which case, override function will not work ?
Did i missed something in CasperJS require function ?

What is wrong with my approach to Javascript Inheritance?

I know there are tons of ways of doing JS inheritance. I am trying to do something here, where I am passing in rows into my sub class, and i want to pass it through to the super class at constructor time :
function AbstractTableModel(rows) {
this.showRows = function() {
alert('rows ' + this.rows);
}
}
function SolutionTableModel(rows) {
this.prototype = new AbstractTableModel(rows);
this.show = function() {
this.protoype.showRows();
};
}
var stm = new SolutionTableModel(3);
stm.show();
fiddle :
http://jsfiddle.net/YuqPX/2/
It doesnt seem to work because the prototype methods are not flowing down :( Any ideas?
Live Demo
First you must define this.rows
function AbstractTableModel(rows) {
this.rows = rows;
this.showRows = function() {
alert('rows ' + this.rows);
};
}
Second, if you want to inherit from AbstractTableModel you ought to do so...
function SolutionTableModel(rows) {
AbstractTableModel.call(this, rows);
this.show = function() {
this.showRows();
};
}
SolutionTableModel.prototype = new AbstractTableModel();
var stm = new SolutionTableModel(3);
stm.show();
/==============================================================================/
Also you can use Parasitic Combination Inheritance Pattern, if you want to avoid calling base constructor twice:
function inheritPrototype(subType, superType) {
var prototype = Object.create(superType.prototype, {
constructor: {
value: subType,
enumerable: true
}
});
subType.prototype = prototype;
}
function AbstractTableModel(rows) {
this.rows = rows;
this.showRows = function () {
alert('rows ' + this.rows);
};
}
function SolutionTableModel(rows) {
AbstractTableModel.call(this, rows);
this.show = function () {
this.showRows();
};
}
inheritPrototype(AbstractTableModel, SolutionTableModel);
var stm = new SolutionTableModel(3);
stm.show();
function AbstractTableModel(rows) {
this.rows = rows;
this.showRows = function() {
alert('rows ' + this.rows);
}
}
function SolutionTableModel(rows) {
var soln = Object.create(new AbstractTableModel(rows));
soln.show = function() {
this.showRows();
};
return soln;
}
var solution = new SolutionTableModel(5);
solution.show();
This is one way of doing the object inheritance. This method is most elegant in my opinion and can be found in detail here
Fiddle
function AbstractTableModel(rows) {
this.rows = rows;
}
AbstractTableModel.prototype.showRows = function() {
console.log('rows ' + this.rows);
}
function SolutionTableModel(rows) {
AbstractTableModel.call(this, rows);
this.show = function() {
this.showRows();
};
}
SolutionTableModel.prototype = Object.create(AbstractTableModel.prototype);
var stm = new SolutionTableModel(3);
stm.show();
here is a working example based on what you have done DEMO:
function AbstractTableModel(rows) {
this.showRows = function () {
alert('rows ' + rows);
}
}
function SolutionTableModel(rows) {
var self = this;
this.prototype = new AbstractTableModel(rows);
this.show = function () {
self.prototype.showRows();
};
}
var stm = new SolutionTableModel(3);
stm.show();
In your class AbstractTableModel there is no this.rows just use rows directly.
The same catch in the second class SolutionTableModel. I prefer to define variable self that points to the created instance of the object.
You miss type protoype it should be prototype

how to call function using name such as "function someName(){}"?

I have a name of a private function in JavaScript as a string, how do I call that function?
var test = function () {
this.callFunction = function(index) {
return this["func" + index]();
}
function func1() { }
function func2() { }
...
function funcN() { }
}
var obj = new test();
obj.callFunction(1);
func1 and friends are local variables, not members of the object. You can't call them like that (at least not in any sane way).
Define them with function expressions (instead of function declarations) and store them in an array.
var test = function () {
this.callFunction = function(index) {
return funcs[index]();
}
var funcs = [
function () {},
function () {},
function () {}
];
}
var obj = new test();
obj.callFunction(0);
As your code stands, the functions are not present as properties of the instance. What you need to do is create them as properties of the context.
var test = function () {
this.callFunction = function(index) {
return this["func" + index];
}
this.func1 = function() { }
this.func2 = function() { }
...
}
var obj = new test();
obj.callFunction(1)();
you can use eval
var test = function () {
this.callFunction = function(index) {
return eval("func" + index + '()');
}
function func1() {
return 1;
}
function func2() {
return 2;
}
function funcN() { }
};
var obj = new test();
obj.callFunction(2);
eval is evil
You can use a private array of functions:
var test = function() {
var func = [
function() { return "one" },
function() { return "two"; }
]
this.callFunction = function(index) {
return func[index]();
}
}
var obj = new test();
var ret = obj.callFunction(1);
console.log(ret);​
​
http://jsfiddle.net/V8FaJ/

Categories

Resources