ReferenceError:变量未定义1

时间:2019-03-30 11:03:40

标签: javascript

首先,不是重复,我确实在此处查看了其他“ 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
}

5 个答案:

答案 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