首先,不是重复,我确实在此处查看了其他“ ReferenceErrors”。但是,我的问题与范围无关,也不是拼写错误。
我的问题是,尽管我在第一行就明确定义了副本,但显然未定义副本。 发生了什么事?
我的目标是在循环内部重新定义变量copy
。
var copy = 'test 1';
for (let i = 0; i < 2; i++) {
let t = copy.replace(/(\d+)/, function (fullMatch, n) {return `${Number(n) + 1}`;});
console.log(t); // Output: 'test 2';
let copy = t; // <-- ReferenceError: copy is not defined
}
答案 0 :(得分:2)
我想这里的问题是您试图在循环中声明两次复制变量:
let copy = t;
解决方案是按以下方式从for循环中删除let:
var copy = 'test 1';
for (let i = 0; i < 2; i++) {
let t = copy.replace(/(\d+)/, function (fullMatch, n) {return `${Number(n) + 1}`;});
console.log(t);
copy = t; // removed let
}
因此,您不必声明两次复制变量。
此外,我建议阅读标题为What's the difference between using “let” and “var”?的文章。
答案 1 :(得分:1)
这是由于临时死区而发生的,您使用let
声明了具有块范围的副本,因此在这种情况下,它仅限于for循环的范围。 / p>
现在在for循环内,您正在尝试访问copy
,以为它是使用var
声明的外部变量,但事实并非如此,它实际上是指内部{{1} }使用copy
声明。
使用let
声明的变量不会被提升到顶部,因此不能在声明之前使用。这种现象称为temporal dead zone。
使用let
声明的变量也是如此。
const
要解决此问题,请勿使用for (let i = 0; i < 2; i++) {
let t = copy.replace(/(\d+)/,... //copy is actually not available here, accessing it here will result in a ReferenceError
...
let copy = t; //copy will be available after this declaration
再次声明它,只需重新分配外部变量即可:
let
答案 2 :(得分:0)
这是一个Temporal dead zone (TDZ)问题。
在循环中,将副本提升到循环的顶部。但是,它不是像var这样未定义的,而是“未初始化的”,访问它会引发错误。
var copy = 'test 1';
for (let i = 0; i < 2; i++) {
// copy is hoisted here
// It is not initialized
//Accessing copy here throws ReferenceError
let t = copy.replace(/(\d+)/, function (fullMatch, n) {return `${Number(n) + 1}`;});
console.log(t); // Output: 'test 2';
let copy = t; // <-- ReferenceError: copy is not defined
}
答案 3 :(得分:0)
之所以会这样,是因为您两次声明了copy,但这只是事实的一半。
看此代码将起作用。请注意,您两次声明了副本。但这不会引发未定义的错误
var copy = 'test 1';
for (let i = 0; i < 2; i++) {
let copy = t;
}
这肯定会引发错误
var copy ='test 1';
for (let i = 0; i < 2; i++) {
let t = copy.replace(/(\d+)/, function (fullMatch, n) {return `${Number(n) + 1}`;});
let copy = t;
}
这是因为let copy
。 let copy的作用域在for循环内。
编译器将始终尝试查找与您调用的函数最接近的变量。
因此会抛出未定义的错误。在您的情况下,您尝试调用var copy
,但是编译器发现了let copy
,这就是为什么它不返回错误的原因在于let复制本身而不是这些行
let t = copy.replace(/(\d+)/, function (fullMatch, n) {return `${Number(n) + 1}`;});
答案 4 :(得分:0)
您可以像这样使用它:
var copy = 'test 1';
for (let i=0; i<2; i++) {
let t = copy.replace(/(\d+)/, function (fullMatch, n) {return `${Number(n) + 1}`;});
console.log(t); // Output: 'test 2';
copy = t; // <-- ReferenceError: copy is not defined
}
或使用新的变量名称,例如:let copy1 为了避免ReferenceError