Reputation: 2224
I have the following Pet
and cat
inherits from Pet
, as follows:
function Pet(){};
Pet.prototype.run = function takeoff(cb, sec) {
setTimeout(function() {
cb();
console.log('Run');
}, sec);
};
Pet.prototype.bark = function bark(cb, sec) {
setTimeout(function() {
cb();
console.log('bark');
}, sec);
};
Pet.prototype.comeback = function comeback(cb, sec) {
setTimeout(function() {
cb();
console.log('Comeback');
}, sec);
};
var cat = new Pet();
cat.prototype = Object.create(Pet);
cat.prototype.run = function(){
var that = this;
that.run = Pet.prototype.run.call(that);
return that;
}
cat.prototype.bark = function(){
this.bark = Pet.prototype.bark.call(this);
return this;
}
cat.prototype.comeback = function(){
this.comeback = Pet.prototype.comeback.call(this);
return this;
}
console.log(cat);
cat.run().bark().return();
In this situation, the cat
and Pet
have the same function names. The only difference is return this
is added to cat
methods to make method chaining possible in cat
but not Pet
. However, note that I have to write the name of the function every time and set the same name to its parent's prototype. Is it possible to generalize this so that any method I specify for Pet
will be duplicated in cat
but yet I don't have to specify the method for cat
every time?
Upvotes: 0
Views: 89
Reputation: 392
After a discussion with guest I came up with a solution that extends each function to use a promise. The code will be executed in order and the object will be chained.
function Pet(){};
Pet.prototype.run = function run(callback) {
setTimeout(function() {
callback()
console.log('Run');
}, 1000);
};
Pet.prototype.bark = function bark(callback) {
setTimeout(function() {
callback()
console.log('Bark');
}, 500);
};
Pet.prototype.comeBack = function comeBack(callback) {
setTimeout(function() {
callback()
console.log('Comeback');
}, 750);
};
// DON'T MODIFY ANYTHING ABOVE HERE
// START ADD YOUR CODE HERE
function createChainableFunction(fun) {
var that = this;
return function() {
if(!that.promise) {
that.promise = new Promise(function(resolve, reject) {
fun.call(that, resolve);
});
}
else {
that.promise.then(function() {
that.promise = new Promise(function(resolve) {
fun.call(that, resolve);
});
});
}
return this;
}
}
function isFunction(functionToCheck) {
var getType = {};
return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]';
}
function createChainable(object) {
var chainable = {
'promise': null
};
chainable.prototype = Object.getPrototypeOf(object);
for(var prop in object) {
if(isFunction(object[prop])) {
chainable[prop] = createChainableFunction.call(chainable.prototype, object[prop], prop);
}
}
return chainable;
}
var cat = createChainable(new Pet());
cat.run().bark().comeBack();
Upvotes: 1
Reputation: 24925
You can add a property in child classes and based on this value, you can return this
.
// Parent Class
function Pet() {
this.sec = 1000
};
Pet.prototype.run = function takeoff(cb, sec) {
setTimeout(function() {
//cb();
console.log('Run');
}, sec || this.sec);
if (this.animalName) return this;
};
Pet.prototype.bark = function bark(cb, sec) {
setTimeout(function() {
//cb();
console.log('bark');
}, sec || this.sec);
if (this.animalName) return this;
};
Pet.prototype.comeback = function comeback(cb, sec) {
setTimeout(function() {
//cb();
console.log('Comeback');
}, sec || this.sec);
if (this.animalName) return this;
};
// Child class
var Cat = function() {
this.animalName = 'Cat'
}
// Linking of classes
Cat.prototype = new Pet();
// object of child class
var cat = new Cat();
cat.run().bark().comeback()
var pet = new Pet();
try {
// Chaining not allowed.
pet.run().bark().comeback()
} catch (ex) {
console.log(ex.message)
}
Upvotes: 1