Coffeescript 在嵌套循环中关闭此引用列表
Coffescript closure _this reference lost within nested loops
这是我观察到的关于 CoffeeScript 的一些有趣的东西。
TLDR:{
我们知道粗箭头 (=>
) 会生成一个闭包保存对 this
的引用,并且 @
的每个引用都将替换为 [=16] 的原始值=].因此,以下 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];
这是正常行为,还是错误?
仔细观察内循环:
results.push((function() {
var j, len1, ref, results1;
ref = this.sth;
// Loop stuff goes here...
}).call(_this));
内部循环包含在一个函数中(作为循环理解代码的一部分),该函数使用 Function.prototype.call
:
进行评估
The call()
method calls a function with a given this
value and arguments provided individually.
call
是用 _this
调用的(=>
中的 stashed/bound @
)所以 this
在该函数中实际上是 _this
一切都很好。
如果您通过显式不返回任何内容来抑制理解代码:
=>
for a in sth
for b in @sth
sth
return
然后您会看到您最初期望的ref = _this.sth
:
(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);
这是我观察到的关于 CoffeeScript 的一些有趣的东西。
TLDR:{
我们知道粗箭头 (=>
) 会生成一个闭包保存对 this
的引用,并且 @
的每个引用都将替换为 [=16] 的原始值=].因此,以下 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];
这是正常行为,还是错误?
仔细观察内循环:
results.push((function() {
var j, len1, ref, results1;
ref = this.sth;
// Loop stuff goes here...
}).call(_this));
内部循环包含在一个函数中(作为循环理解代码的一部分),该函数使用 Function.prototype.call
:
The
call()
method calls a function with a giventhis
value and arguments provided individually.
call
是用 _this
调用的(=>
中的 stashed/bound @
)所以 this
在该函数中实际上是 _this
一切都很好。
如果您通过显式不返回任何内容来抑制理解代码:
=>
for a in sth
for b in @sth
sth
return
然后您会看到您最初期望的ref = _this.sth
:
(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);