在 JavaScript (JSLint) 中的 for 循环之外引用“this”元素

Posted

技术标签:

【中文标题】在 JavaScript (JSLint) 中的 for 循环之外引用“this”元素【英文标题】:Reference "this" element outside of a for-loop in JavaScript (JSLint) 【发布时间】:2017-03-01 15:06:24 【问题描述】:

提前感谢您的帮助!

我正在创建一个简单的井字游戏来帮助我学习原生 javascript,所以我的目标是在没有 jQuery 或 html/CSS 的情况下尽可能多地完成游戏。

我正在使用 for-loop 创建多个 div 元素,遵循 JSLint。我在创建div 元素的过程中附加了一个.addEventListener(),以在单击时更改特定 div 的背景颜色。

我一直在搜索 ***,试图使用 this 来引用特定的 div 点击。到目前为止,我成功的唯一方法是在我的for-loop 中使用匿名函数within。 JSLint 没有留下深刻印象,我明白了:

不要在循环中创建函数。

当我尝试调用外部函数并传入this 时,整个div 创建过程停止工作,我不知道为什么。

我所拥有的(“有效”):https://jsfiddle.net/typj2LLb/4/

// create game
var gameContainer = document.getElementById('board');
var createBoard = function() 
  'use strict';
  var index, square;
  for (index = 0; index < 9; index += 1) 
    square = document.createElement('div');
    square.className = 'tile';

    // tile event
    square.addEventListener('click', function() 
      this.style.backgroundColor = 'yellow';
    );

    gameContainer.appendChild(square);
  
;

createBoard();
.tile 
  display: inline-block;
  height: 25vh;
  width: 30%;
  margin: 0 3px;
  border: 1px solid black;
<body>
  <div id="board"></div>
</body>

我认为我应该做的事情(那行不通):https://jsfiddle.net/e4mstyy9/1/

// click-event
function changeColor(specificElement) 
  'use strict';
  specificElement.style.backgroundColor = 'yellow';


// create game
var gameContainer = document.getElementById('board');
var createBoard = function() 
  'use strict';
  var index, square;
  for (index = 0; index < 9; index += 1) 
    square = document.createElement('div');
    square.className = 'tile';

    // tile event
    square.addEventListener('click', changeColor(this));

    gameContainer.appendChild(square);
  
;

createBoard();
.tile 
  display: inline-block;
  height: 25vh;
  width: 30%;
  margin: 0 3px;
  border: 1px solid black;
<body>
  <div id="board"></div>
</body>

【问题讨论】:

始终在评论中包含相关代码或您的代码。您甚至可以使用 stack sn-ps 而不是 jsfiddle 来创建内联可运行示例。 啊,谢谢菲利克斯。我会确保在未来这样做。 【参考方案1】:

仅当您在函数内引用循环变量(或从该变量派生的变量)时,不在循环内创建函数的建议才有意义(请参阅JavaScript closure inside loops – simple practical example 了解原因)。

但是由于您没有这样做,因此您的代码非常好,您可以继续使用它。


为什么第二个例子不起作用?

当你有foo(bar())这样的表达式时,bar将被调用first,它的返回值将被传递给foo

在您的代码中,您有square.addEventListener('click', changeColor(this));。这意味着首先执行changeColor,并将其返回值传递给addEventListener

但是,引擎甚至没有走那么远,因为执行 changeColor(this) 会引发错误

未捕获的类型错误:无法读取未定义的属性“样式”

这是因为您传递给changeColor (this) 的值不是DOM 元素。由于你使用的是严格模式,this 的值为undefined,所以你正在执行changeColor(undefined)

在不创建循环体中的函数的情况下解决此问题的一种方法是简单地传递 changeColor 而不是调用它(这需要我们再次使用 this):

// click-event
function changeColor() 
  this.style.backgroundColor = 'yellow';


// ...

square.addEventListener('click', changeColor);

这实际上是一个很好的改变,因为该函数只被创建一次并被重复使用,而不是为每个元素创建一个新的事件处理程序。

【讨论】:

我们可以有 function changeColor() this.style.backgroundColor = 'yellow'; 并像这样传递它:square.addEventListener('click', changeColor)); jsfiddle.net/typj2LLb/7 @lampyridae:是的,这更有意义。我会更新帖子。

以上是关于在 JavaScript (JSLint) 中的 for 循环之外引用“this”元素的主要内容,如果未能解决你的问题,请参考以下文章

eslint 或 jslint 中的 Javascript lambda/匿名函数长度警告

无法使用内联代码删除 Aptana 中的 Javascript JsLint 错误

如何使用 jenkins 中的 jslint 和违规插件查找特定错误?

JSLint 严格违规。面向对象的 Javascript 挫折

JSLint检测Javascript语法规范

Jquery 和 Jslint - 在定义之前使用了“$”