以下工作正常:
//Returns an object with an "id" of 1, which is inside another object, "collection".
//Then, calls .move(), which sets collection's property "coordinates" to {x: 20, y: 20}
collection.get(1).move(20,20);
console.log(collection.get(1).get('coordinates')); //returns { x: 20, y: 20 }
这是有效的,因为集合.get()方法执行返回此;
因此,该方法是可链接的。
然而,这不起作用:
collection.get(1) //returns the object inside "collection" that has an "id" of 1
.get('coordinates') //returns that object's current "coordinates" { x: 20, y: 20 }
.move(20,20); //error
这是因为带有id:1“.get()方法的”对象看起来与此类似:
Thing.prototype = {
id: null,
get: function(prop) {
if (prop == 'id') {
return this.id;
} else {
return this.attributes[prop];
}
}
}
(顺便说一句,当对象Thing被初始化时,id就会被设置。)正如你所看到的,这个单独的.get()方法已经返回一个值(它的对象的某个属性)。
因此,考虑到现在设置代码的方式,该方法是不可链接的。
为了把它包装起来,我的“收藏品”包含了一系列“东西”。每个集合都有一个 .get()方法,它从的集合的数组中返回 thing 事。此外,每个 thing 都有一个 .get()方法,它从 thing 中的特定属性返回一个值。
我遇到的问题是,如果可能的话,我想制作单独的 thing .get()方法可链接...但是,我无法调用这两行代码同一块:
return this[prop];
return this;
例如,我查看了one of John Resig's slides的代码摘录:
Function.prototype.bind = function(){
var fn = this, args = Array.prototype.slice.call(arguments), object = args.shift();
return function(){
return fn.apply(object,
args.concat(Array.prototype.slice.call(arguments)));
};
};
显示了通过使用回调函数返回一些不同的东西的例子(我认为)。
我已经尝试了几种不同的方法来解决这个问题,但是没有用,包括使用返回对象的回调返回另一个方法的对象。
任何推动正确的方向都将受到赞赏。
答案 0 :(得分:2)
一个函数只能返回一个东西。如果它的目的是返回关于对象的数据,它也不能返回对象本身。您只能链接用于副作用的方法或返回相关集合。
答案 1 :(得分:0)
如果您只关心对子对象执行操作,您可以查看jQuery的addBack
和end
以获取灵感。也就是说,我不确定它是非常好的API设计;如果你只是将一个中间结果放在一个变量中并使用多个语句,那么用法会更清楚,即使这不是那么“光滑”。
答案 2 :(得分:0)
最重要的是,如果你想保持链条运行,你的函数必须返回对象本身;这是一种方法:
get: function(prop, callback) {
if (prop == 'id') {
callback(this.id);
} else {
callback(this.attributes[prop]);
}
return this;
}
这使得它可以再次链接,因为数据提取的副作用现在已被隔离,但结果逻辑可能看起来有点滑稽:
collection.get(1)
.get('coordinates', function(value) {
// whatever
})
.move(20,20);