复制下划线的链方法风格

在下面你的函数cat可以调用eatplay功能的情况下直接实例化一个新的cat对象,这是由值传递从功能cat.eatcat.play函数来获取状况证明。复制下划线的链方法风格

var cat = function(obj){ 

// if (obj instanceof cat) return obj;

// if (!(this instanceof cat)) return new cat(obj);

// this.catwrapped = obj;

}

cat.eat = function(food){

if(food == "tuna") return 95

if(food == "milk") return 35

return 0

}

cat.play = function(energy){

if(energy < 50) return 0

return 100

}

var energy = cat.eat("tuna")

var status = cat.play(energy)

console.log(status) // 100

我试图保持此功能并添加下划线样式链接。所以你可以做到以下几点。这是如何实现的?

cat.day = function(obj){ 

var instance = cat(obj);

// instance._chain = true;

return instance;

}

var status = cat.day()

.eat("tuna")

.play()

.status()

console.log(status) // should log 100

那是我必须catcat.day,使这项工作最少的代码?

回答:

我创建了一个NPM模块underscore-chainable完成这一点。

npm install underscore-chainable 

然后

var _ = require("underscore") 

_.mixin(require("underscore-chainable"))

var cat = _.makeChainable() // make the `cat` object chainable

cat.eat = function(food){

if(food == "tuna") return 95

if(food == "milk") return 35

return 0

}

cat.play = function(energy){

if(energy < 50) return 0

return 100

}

_.extendChainable(cat) // extend the chainablity

// adds `.chain` and `.value`

var energy = cat.eat("tuna")

var status = cat.play(energy)

console.log(status) // 100

var status = cat

.chain("tuna")

.eat()

.play()

.value()

console.log(status) // 100

回答:

您需要返回对象的指针,以便能够执行链来电:

cat.play = function(energy){ 

// do something with energy

return cat

}

cat.eat = function(food){

// do something with food

return cat

}

var status = cat.day()

.eat("tuna")

.play()

.status()

由于您使用的是不同的目的回报(后忽略它),你需要重新考虑你的程序算法

更新。你可以创造什么将执行任务或返回从参数取决于数据的功能:

var energy = 0; 

cat.eat = function(v) {

// return something on empty call

if (!arguments.length) return energy

// process passed data

energy += v

// return cat object to allow chaincals

return cat

}

在这种情况下cat.eat(10)将允许你进行通话链,而cat.eat()将回报你的价值,储存在能源

Update2:你的函数不会改变任何内部变量,所以任何数据都会在一个标准的链式调用中丢失。你做什么,你需要一个管道,并将一个功能直接输出到另一个输入。有方式如何做到这一点的数字:

你可以尝试使用下划线减少功能:

var status = _.reduce([cat.play, cat.eat], function(status, f){ return f(status); }, "tuna"); 

或者你也可以直接打电话给他们:

cat.status(cat.play(cat.eat("tuna"))) 

如果创建内部变量存储能量,你甚至可以调用下划线链:

var cat = function() { 

this.energy = 0;

}

cat.eat = function(food){

if (food == "tuna") cat.energy = 95

else if(food == "milk") cat.energy = 35

else cat.energy = 0

}

cat.play = function(){

if(cat.energy < 50) cat.energy = 0

else cat.energy = 100

}

var status = _.chain(cat)

.eat("tuna")

.play()

.value()

.energy

但它似乎有点冗余t

回答:

我抄出了所有可以链接的下划线函数,并将其添加到对象的末尾。

这个想法是你可以创建类似于普通函数的函数,执行某种输入/输出操作。然后,您可以遍历所有这些函数,并构建与创建对象链相关的原型,如存储数据和传输参数。

var _ = require("underscore") 

var cat = function(obj) {

if (obj instanceof cat) return obj;

if (!(this instanceof cat)) return new cat(obj);

this._wrapped = obj;

};

cat.eat = function(food){

if(food == "tuna") return 95

if(food == "milk") return 35

return 0

}

cat.play = function(energy){

if(energy < 50) return 0

return 100

}

// Add a "chain" function. Start chaining a wrapped Underscore object.

cat.chain = function(obj) {

var instance = cat(obj);

instance._chain = true;

return instance;

};

// Helper function to continue chaining intermediate results.

var chainResult = function(instance, obj) {

return instance._chain ? cat(obj).chain() : obj;

};

var ArrayProto = Array.prototype

var push = ArrayProto.push

cat.mixin = function(obj) {

_.each(_.functions(obj), function(name) {

var func = cat[name] = obj[name];

cat.prototype[name] = function() {

var args = [this._wrapped];

push.apply(args, arguments);

return chainResult(this, func.apply(cat, args));

};

});

};

// Add all of the Underscore functions to the wrapper object.

cat.mixin(cat);

// Extracts the result from a wrapped and chained object.

cat.prototype.value = function() {

return this._wrapped;

};

// var energy = cat.eat("tuna")

// var status = cat.play(energy)

//

// console.log(status) // 100

var status = cat.chain("tuna")

.eat()

.play()

.value()

console.log(status) // 100

UPDATE:

我发的功能,使任何对象可链接的对象下划线混入。

这里的混入:

var _ = require("underscore") 

_.mixin({

prototypeChain: function(thObj){

return function(obj) {

var instance = thObj(obj);

instance._chain = true;

return instance;

}

},

prototypeExtend: function(theObj){

var chainResult = function(instance, obj) {

return instance._chain ? theObj(obj).chain() : obj;

}

var prototypes = _.map(_.functions(theObj), function(name) {

var func = theObj[name];

theObj.prototype[name] = function() {

var args = [this._wrapped];

Array.prototype.push.apply(args, arguments);

return chainResult(this, func.apply(theObj, args));

};

});

_.extend(theObj, prototypes)

},

prototypeValue: function(){

return function(){

return this._wrapped;

}

}

})

下面是它如何工作的:

var cat = function(obj) { 

if (obj instanceof cat) return obj;

if (!(this instanceof cat)) return new cat(obj);

this._wrapped = obj;

};

cat.eat = function(food){

if(food == "tuna") return 95

if(food == "milk") return 35

return 0

}

cat.play = function(energy){

if(energy < 50) return 0

return 100

}

cat.chain = _.prototypeChain(cat)

_.prototypeExtend(cat)

cat.prototype.value = _.prototypeValue()

var energy = cat.eat("tuna")

var status = cat.play(energy)

console.log(status) // 100

var status = cat.chain("tuna")

.eat()

.play()

.value()

console.log(status) // 100

以上是 复制下划线的链方法风格 的全部内容, 来源链接: utcz.com/qa/265484.html

回到顶部