DOM,ThreeJS和现在canvas都编写了库以提供方法链接(也许是jQuery最熟悉的)。链接也是used in core C libraries。
这些fluent interfaces避免了不必要的重复感兴趣的对象。比较:
var cx = cq(640, 480);
cx.drawImage(image, 0, 0);
cx.fillStyle("#ff0000");
cx.fillRect(64, 64, 32, 32);
cx.blur();
cx.appendTo("body");
为:
cq(640, 480)
.drawImage(image, 0, 0)
.fillStyle("#ff0000")
.fillRect(64, 64, 32, 32)
.blur()
.appendTo("body");
可以说,以前的“传统”风格过于冗长,违反了DRY。
为避免重复cx
变量,某些语言允许我们使用with
语句表达一组调用:
with ( cq(640, 480) ) {
drawImage(image, 0, 0);
fillStyle("#ff0000");
fillRect(64, 64, 32, 32);
blur();
appendTo("body");
}
虽然JavaScript的with
语句为dangerous in the presence of typos,但Scala的限制性更强with
语句可以安全使用,而且Haxe还通过其using
向本地范围提供函数导入关键词。不幸的是,Java和C没有提供这样的捷径,迫使我们在传统代码或链接之间做出选择。
语言作者是否应该考虑使用类似安全with
的语句作为方法链的替代方法,还是有充分理由避免它?如果需要这样的功能,应该采用什么形式?
我对方法链的一个担忧是,在编译重复使用cx
的代码时,链中后来调用主题的模糊性可能阻止优化 。例如,如果对cx
方法的调用不重叠,则它们可以并行化,但编译器在链接的示例中可能更难确定这一点。
rambo指出,另一个缺点是,为链接设计的方法无法返回任何其他值,这似乎相当浪费。
答案 0 :(得分:2)
它被称为Method Chaining。它经常出现在Fluent Interface的讨论中。
也许最大的缺点是你不能返回一个值,因为你必须返回隐含的对象以允许链接。如果没有返回值,并非所有方法都有意义,那么最终会得到一个具有一些可链接方法的接口,而有些则没有。
我不认为它表示缺少语言功能,因为没有它就没有严重的功能损失。但是对这样的某些人的语言支持可能会很有趣。
答案 1 :(得分:1)
这不是一种缺少语言的功能,而是一种语言功能。如果它丢失了,则无法在Javascript中执行此操作。
这不是语法。相反,它是一种设计模式。它被称为链接。事实上,有些库只能实现链接。例如,DED |链是一个为YUI2实现链接的库,它不是用链接编写的。
像with
这样的专门语法(确实在js中实现,就像你提到的那样)无论你怎么称呼它都是有问题的(你建议使用名称“on”但它会有所有“with”的问题有)。
问题是,在代码块中,它可能会让人混淆(编译器不会混淆)天气方法或变量是指对象的方法,或者是否存在拼写错误并且它意外地引用了全局变量或变量不属于对象但属于范围。
当然,您可以说程序员的工作是确保他们不使用可能导致混淆的变量和方法名称。在这种情况下,您可以使用with
。