在方法链中使用函数调用者名称

时间:2016-10-17 07:50:20

标签: javascript method-chaining

我有以下Petcat继承自Pet,如下所示:

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

在这种情况下,catPet具有相同的功能名称。唯一的区别是return this已添加到cat方法,以便在cat而非Pet中进行方法链接。但请注意,我必须每次都写出函数的名称,并为其父级原型设置相同的名称。是否可以对此进行概括,以便我在Pet中为cat指定的任何方法都会重复,但我不必每次都为cat指定方法?

2 个答案:

答案 0 :(得分:1)

您可以在子类中添加属性,并根据此值返回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)
}

答案 1 :(得分:1)

在与客人讨论后,我提出了一个解决方案,扩展每个功能以使用承诺。代码将按顺序执行,对象将被链接。

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