Javascript全局作用域误解

Javascript Global Scope Misinterpretation

本文关键字:误解 作用域 全局 Javascript      更新时间:2023-09-26

我经常遇到这个问题,我想我终于需要一个解释了。我有谷歌浏览器,经常使用javascript控制台。当我声明一个全局变量时,我总是可以在控制台上访问它的内容,但当我试图从一个函数内部访问变量时,当脚本在浏览器中运行时,我得到一个"无法读取属性'顶部'的未定义"类型错误。

我将粘贴一段代码在这里,如果有人能解释给我为什么我得到这个错误,我将非常感激!
// JavaScript Document
var myglobalvariable;
// ...
$(document).ready( function() {
  myglobalvariable = document.getElementsByTagName("article");
  // ...
});
function myFunction() {
  for (i in myglobalvariable) {
    mylocalvariable_top = myglobalvariable[i].style.top; // Error points to this line
  // ...
  }
}

myFunction通常会被事件处理程序调用并报告上面提到的错误。

正如其他人所说,最好避免数组使用for ... in。也就是说,为了澄清产生此错误的误解,您应该这样写:

function myFunction() {
  for (i in myglobalvariable) {
    mylocalvariable_top = i.style.top; // <-- i IS the element
                                       // <-- for clarity you should probably rename "i" to
                                       //    "element" or something more descriptive which will
                                       //      make clear it is not a numerical index
  // ...
  }
}

也就是说,查找myglobalvariable[i]是没有意义的,因为在您的情况下,i已经表示"数组myglobalvariable的第i个元素"

您只是将典型的for循环的约定与for... in结构的约定混淆了。

这将创建节点的NodeList

$(document).ready( function() {
  myglobalvariable = document.getElementsByTagName("article");
  // ...
});

遍历每个节点 NodeList对象上的任何附加属性。

function myFunction() {
  for (i in myglobalvariable) {
    mylocalvariable_top = myglobalvariable[i].style.top; // Error points to this line
  // ...
  }
}

也就是说,您可以在myglobalvariable中遇到不是节点且没有style属性的项目。特别是,在迭代过程中的某个时刻,i将成为itemlength

这将更安全地遍历列表:

function myFunction() {
  for (var i = 0; i < myglobalvariable.length; i++) {
    mylocalvariable_top = myglobalvariable[i].style.top; // Error points to this line
  // ...
  }
}

我怀疑你正在做的不是你想要的。

for (i in myglobalvariable) { }

这不是遍历数组中的项,而是遍历对象的键/属性名。

myglobalvariable[i]

上面你访问的是带有该键的属性的类型。

myglobalvariable[i].style.top

上面你访问了该对象的style属性。如果该对象没有样式属性,那么这将是未定义的。这意味着当你在一个不存在的属性上调用。top时,你会得到"Cannot read property 'top' of undefined"。

你在这里提出的是一个具体的问题,而不是一般的"全局范围的误解"。

<<p> 解决方案/strong>
var i, len = myglobalvariable.length;
for (i = 0; i < len; i++) {
    if (myglobalvariable[i].style)
        mylocalvariable_top = myglobalvariable[i].style.top;
  // ...
}