在 JavaScript (JSLint) 中的 for 循环之外引用 "this" 元素
Reference "this" element outside of a for-loop in JavaScript (JSLint)
预先感谢您的帮助!
我正在创建一个简单的井字游戏来帮助我学习母语 JavaScript,所以我的目标是在没有 jQuery 或 [=62= 的情况下尽可能多地做] 为游戏。
我正在使用 for-loop
创建多个 div
元素,遵循 JSLint。我附加了一个 .addEventListener()
作为创建 div
元素的过程的一部分,以在单击时更改 特定 div
的背景颜色。
我一直在搜索 Whosebug,试图使用 this
来引用特定的 div
单击。到目前为止,我唯一成功的方法是在 我的 for-loop
中使用匿名函数 。 JSLint 没有留下深刻印象,我得到:
Don't make functions within a loop.
当我尝试调用外部函数并传入 this
时,整个 div
创建过程就停止了,我不确定为什么。
我有什么(那个"works"):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>
不在循环内创建函数的建议仅在您在函数内引用 循环变量(或从该变量派生的东西)时才有意义(参见 JavaScript closure inside loops – simple practical example 为什么)。
但是因为你没有这样做,所以你的代码非常好,你可以继续使用它。
为什么第二个例子不起作用?
当你有一个表达式如foo(bar())
时,bar
将被调用first及其return值 将传递给 foo
。
在您的代码中有 square.addEventListener('click', changeColor(this));
。这意味着 changeColor
首先执行,其 return 值传递给 addEventListener
.
但是,引擎甚至还没有走到那一步,因为执行 changeColor(this)
会抛出错误
Uncaught TypeError: Cannot read property 'style' of undefined
那是因为您传递给 changeColor
(this
) 的值不是 DOM 元素。由于你使用的是严格模式,this
的值为undefined
,所以你执行的是changeColor(undefined)
.
解决此问题而不在循环体内创建函数的一种方法是简单地传递 changeColor
而不是调用它(这需要我们再次使用 this
):
// click-event
function changeColor() {
this.style.backgroundColor = 'yellow';
}
// ...
square.addEventListener('click', changeColor);
这实际上是一个很好的更改,因为该函数只创建 一次 并重复使用,而不是为每个元素创建一个新的事件处理程序。
预先感谢您的帮助!
我正在创建一个简单的井字游戏来帮助我学习母语 JavaScript,所以我的目标是在没有 jQuery 或 [=62= 的情况下尽可能多地做] 为游戏。
我正在使用 for-loop
创建多个 div
元素,遵循 JSLint。我附加了一个 .addEventListener()
作为创建 div
元素的过程的一部分,以在单击时更改 特定 div
的背景颜色。
我一直在搜索 Whosebug,试图使用 this
来引用特定的 div
单击。到目前为止,我唯一成功的方法是在 我的 for-loop
中使用匿名函数 。 JSLint 没有留下深刻印象,我得到:
Don't make functions within a loop.
当我尝试调用外部函数并传入 this
时,整个 div
创建过程就停止了,我不确定为什么。
我有什么(那个"works"):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>
不在循环内创建函数的建议仅在您在函数内引用 循环变量(或从该变量派生的东西)时才有意义(参见 JavaScript closure inside loops – simple practical example 为什么)。
但是因为你没有这样做,所以你的代码非常好,你可以继续使用它。
为什么第二个例子不起作用?
当你有一个表达式如foo(bar())
时,bar
将被调用first及其return值 将传递给 foo
。
在您的代码中有 square.addEventListener('click', changeColor(this));
。这意味着 changeColor
首先执行,其 return 值传递给 addEventListener
.
但是,引擎甚至还没有走到那一步,因为执行 changeColor(this)
会抛出错误
Uncaught TypeError: Cannot read property 'style' of undefined
那是因为您传递给 changeColor
(this
) 的值不是 DOM 元素。由于你使用的是严格模式,this
的值为undefined
,所以你执行的是changeColor(undefined)
.
解决此问题而不在循环体内创建函数的一种方法是简单地传递 changeColor
而不是调用它(这需要我们再次使用 this
):
// click-event
function changeColor() {
this.style.backgroundColor = 'yellow';
}
// ...
square.addEventListener('click', changeColor);
这实际上是一个很好的更改,因为该函数只创建 一次 并重复使用,而不是为每个元素创建一个新的事件处理程序。