对于我观察过的CoffeeScript,这是非常有趣的。
TLDR:{
我们知道胖箭头(=>
)生成一个闭包,保存对this
的引用,@
的每个引用都将替换为this
的原始值。因此,以下coffeescript代码:
=>
@sth
将产生以下内容:
(function(_this) {
return (function() {
return _this.sth;
});
})(this);
注意_this.sth
。
}
但这是我发现的一个案例:
=>
for a in sth
for b in @sth
sth
评估为:
(function(_this) {
return (function() {
var a, b, i, len, results;
results = [];
for (i = 0, len = sth.length; i < len; i++) {
a = sth[i];
results.push((function() {
var j, len1, ref, results1;
ref = this.sth;
results1 = [];
for (j = 0, len1 = ref.length; j < len1; j++) {
b = ref[j];
results1.push(sth);
}
return results1;
}).call(_this));
}
return results;
});
})(this);
这有点长,但问题是内部循环通过this.sth
代替_this.sth
。
内环的确切线是:
ref = this.sth;
results1 = [];
for (j = 0, len1 = ref.length; j < len1; j++) {
b = ref[j];
这是正常行为还是错误?
答案 0 :(得分:2)
Look at the inner loop more closely:
results.push((function() {
var j, len1, ref, results1;
ref = this.sth;
// Loop stuff goes here...
}).call(_this));
The inner loop is wrapped in a function (as part of the loop comprehension code) which is evaluated using Function.prototype.call
:
The
call()
method calls a function with a giventhis
value and arguments provided individually.
call
is called with _this
(the stashed/bound @
from the =>
) so this
inside that function is actually _this
and all is well.
If you suppress the comprehension code by explicitly returning nothing:
=>
for a in sth
for b in @sth
sth
return
then you'll see the ref = _this.sth
that you were originally expecting:
(function(_this) {
return (function() {
var a, b, i, j, len, len1, ref;
for (i = 0, len = sth.length; i < len; i++) {
a = sth[i];
ref = _this.sth; # <---------------------------
for (j = 0, len1 = ref.length; j < len1; j++) {
b = ref[j];
sth;
}
}
});
})(this);