【问题标题】:Global and local variables in my script我脚本中的全局变量和局部变量
【发布时间】:2010-04-24 22:51:33
【问题描述】:

我刚开始学习 javascript,并尝试编写一个小脚本来在页面上创建一个 div 网格。

这是脚本:

var tileWidth=50;
var tileHeight=100;
var leftPos=10;
var topPos=10;
var columns=10;
var rows=10;
var spacing=5;

$('document').ready(function() {
 placeTiles();
});

function makeRow() {
 for (var i=0; i<columns; i++) {
   $('#canvas').append('<div class="tile" style="left:' + leftPos + 'px;top:' + topPos + 'px;"></div>');
   var leftPos = leftPos + tileWidth + spacing;
 }
}

function placeTiles() {
 for (var i=0; i<rows; i++) {
  makeRow();
  var topPos = topPos + tileHeight + spacing;
 }
}

目前,创建了 100 个 &lt;div&gt;s,所有这些都具有 10px 的顶部位置和未定义的左侧位置(对于该行中的第一个 &lt;div&gt;)或 NaN。

我应该做些什么不同的事情?为什么makerow() 看不到我的全局leftPos 变量(以及与此相关的所有其他变量)?

谢谢。

【问题讨论】:

  • 不要在leftPos前面使用var,因为你已经在脚本顶部声明了left post
  • leftPos 抱歉,在你的 foreach 中从 "var leftPos" 中删除 var

标签: javascript global-variables scope


【解决方案1】:

“为什么 makerow() 不能看到我的全局 leftPos 变量(以及所有其他变量)?”

因为var 不是声明。它是一个函数(范围)范围的注释。在顶级作用域var 本质上 什么都不做(全局执行上下文/作用域 窗口对象)所以它与window.leftPos = 10 相同或只是@ 987654325@。在 makeRow 中,您基本上拥有:

function makeRow() {
 var leftPos = undefined // this is "hoisted" to the TOP of the function
 for (...) {
  // ...
  leftPos = leftPos + tileWidth + spacing
 }
}

看起来有些可疑? :-)

对此的两种解决方案是 1) 使用不同的变量名(推荐) 2) 使用窗口对象的“全局”leftPos 属性(如下所示)。

此外,即使它只是一个范围范围的注释,如果您将 'var' 保留在顶部,它通常会导致更清晰的代码(无论如何它是“提升”的,见上文)。例如:

function makeRow() {
 var leftPos = window.leftPos // or use a different name, which is what I'd do
 for (var i=0; i<columns; i++) {
   $('#canvas').append('<div class="tile" style="left:' + leftPos + 'px;top:' + topPos + 'px;"></div>')
   leftPos = leftPos + tileWidth + spacing
 }
}

有关详细信息,请参阅: Identifier Resolution, Execution Contexts and Scope Chains

【讨论】:

  • 哦,我想我明白了!当我做var leftPos = leftPos + tileWidth + spacing时,我声明了一个局部变量leftPos,它覆盖了同名的全局变量(实际上是我想要的),但是当我尝试将全局变量分配给它时,它已经被覆盖了!所以我可以使用window.leftPos的替代方法来引用全局变量,或者给全局变量一个不同的名字。谢谢!
  • @Acorn:覆盖可能不是正确的术语。全局变量仍然存在,但由于您有另一个同名的局部变量,全局变量将无法访问,除非您使用 window.leftPost
  • 阴影是我相信的术语。
【解决方案2】:

你声明leftPosvar leftPos 的函数范围,隐藏了全局声明。如果您没有声明某些内容,请不要使用 var

【讨论】:

  • 但是我已经在脚本的开头将leftPos 声明为 gloval var。我想我可以在函数中分配一个同名的局部变量,这样它就可以使用全局变量,向它添加其他变量,然后覆盖它,这样函数中的所有其他循环都将使用局部变量而不是全局变量。然后下次调用该函数时,它将重置回全局变量。所以我不能这样做?
【解决方案3】:

在 JavaScript 中,您可以为变量设置函数范围或全局范围。

如果在不同的作用域中有两个同名的变量,则优先考虑在函数作用域中声明的变量。

因此,您在脚本顶部的全局范围内声明了 leftPostopPos 变量,并且您还在 makeRow()placeTiles() 函数中声明了它们。 var 关键字用于变量声明,不用于变量赋值。

您只需从函数中删除带有var 的变量声明,即可使用全局变量。只需使用:

leftPos = leftPos + tileWidth + spacing;

// and

topPos = topPos + tileHeight + spacing;

但是,您应该考虑完全避免使用全局变量。全局变量是邪恶的。

进一步阅读:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-14
    • 1970-01-01
    • 2019-04-04
    • 2013-10-06
    • 2012-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多