在红宝石中:
-> { 10.times {|i| puts i} }.call
使用Javascript:
(function (){
for (i = 0; i<10; i++){
console.log(i);
}
})()
我来自JS背景,在学习lambdas和Procs时,我的兴趣达到了顶峰,它说这些函数没有被称为的名字。这让我想起了javascript中的匿名函数或IIFE。
这两个例子是否相同?如果没有什么区别?
答案 0 :(得分:0)
这两条线在几乎每个方面都有很大不同。
最接近此Ruby片段的ECMAScript:
-> { 10.times {|i| puts i} }.call
会是这样的:
(() => { 10.times(i => puts(i)) }).call()
不幸的是,数字在ECMAScript中没有方法,所以我们不得不求助于这样的事情:
(() => { times(10, i => puts(i)) }).call()
显然,为了实现这一点,我们需要添加一些Ruby库支持代码:
(() => { times(10, i => puts(i)) }).call()
function times(i, f) { if (i-- === 0) return; else { times(i, f); f(i) }}
function puts(s) { console.log(s) }
这仍然与原始的Ruby语义不太相似,但比你的提议更接近:
i
泄漏到全局范围内,Ruby代码甚至根本不泄漏i
,它位于最里面的块的本地。Proc#call
,ECMAScript也有(Function.prototype.call
)。for
循环,而Ruby代码使用Integer
上的方法进行迭代。Kernel#puts
将隐式写入您定义为默认输出流的任何内容,而您建议的ECMAScript解决方案将明确地始终写入控制台。self
在Ruby中被词法绑定,但this
动态绑定到ECMAScript中的函数对象本身,除非您使用箭头函数文字,它以lexixally方式绑定this
。另一方面,最接近Ruby的相当于:
(function (){
for (i = 0; i<10; i++){
console.log(i);
}
})()
会是这样的:
-> { $i = 0; while $i < 10 do $stdout.puts($i); $i += 1 end }.()
同样,这不是100%等价的:
for
循环(只有for … in
迭代器),所以最接近的是while
循环。.()
只是call
方法的语法糖。this
是动态绑定的,Ruby中的self
是词法。