仔细阅读下面的代码,能不能利用changeColor()在点击button时改变<h2>的颜色?
<h2>万紫千红</h2>
<button style="color:red" name="change-color">变红</button>
<button style="color:blue" name="change-color">变蓝</button>
<button style="color:yellow" name="change-color">变黄</button>
<script>
function changeColor(color) {
document.getElementsByTagName('h2')[0].style.color = color;
}
</script>
我们已经抽象出了函数changeColor(color),注意这个函数是带着参数的。怎么在事件的回调函数里传参呢?(复习)
@想一想@:能不能这样写?
document.getElementsByTagName('button')[0].onclick = changeColor(this.style.color);
复习:事件绑定的应该是一个函数,而不能是函数运行结果(不能传参),怎么办呢?
<button style="color:red" onclick="changeColor(this.style.color)" name="change-color">变红</button>@想一想@:为什么这里的onclick可以直接使用()和this?(复习)可以将行内onclick绑定想象成自带了一个包裹function……
var buttons = document.getElementsByTagName('button');
for (var i = 0; i < buttons.length; i++) {
buttons[i].onclick = function () {
changeColor(this.style.color);//注意这里使用的是this
}
}
buttons[i].onclick = changeColor(buttons[i].style.color);
function changeColor(color) {
return function () {
document.getElementsByTagName('h2')[0].style.color = color;
}
}
但是,假如你选择了这种方式:
for (var i = 0; i < buttons.length; i++) {
buttons[i].onclick = function () {
document.getElementsByTagName('h2')[0].style.color = buttons[i].style.color;
}
}
演示:当事件触发的时候,i 的值为3
@想一想@:为什么呢?
因为事件的绑定和触发是分离的:
怎么破?
for (var i = 0; i < buttons.length; i++) {
//绑定时立即执行
buttons[i].onclick = (function (n) { //为了清晰,形参重命名为n
//立即执行之后返回的还是函数才行
return function () { //n不要声明在这里,否则……
document.getElementsByTagName('h2')[0].style.color = buttons[n].style.color;
}
})(i); //利用此时的i
}
信息量很大,同学们按这三步进行理解:
我们来看一段更简单的代码:
function luckyStack() {
var _price = 986;
return function () {
return ++_price;
} //函数返回了一个函数
}
var getPrice = luckyStack();//typeof getPrice
alert(`"源栈"培训的价格是每周${getPrice()}元!`);
注意,我们再来捋(复习)一遍:
但是,“闭包”出现了!由于:
这就被称之为:闭包。
演示:每调用一次getPrice(),_price均自增一次,说明_price本身一直存在。
关于闭包的定义很多:有的非常宽泛,比如“函数作用域就是闭包”(有道理但可能没意义);有的很学究气,比如
函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起构成闭包(closure)
不明白这个的定义不要紧。同学们只需要理解:
演示:并理解上文for循环中IIFE形成的闭包
演示:将上述代码改成 let i = 986;
能完美解决上述闭包for循环的问题,让每一个匿名function都绑定了循环时的 i 变量值。参考:MDN,(演示:略)
for (let i = 0; i < buttons.length; i++) {
function foo(x) {
var tmp = 3;
return function (y) {
x = x ? x + 1 : 1;
console.log(x + y + tmp);
}
}
var bar = foo(-1);
//或者:var bar = foo(1);
//或者:var bar = foo(0);
bar(10);
function buildList(list) {
var result = [];
for (vari = 0; i < list.length; i++) {
result.push(function () {
console.log('item' + i + ': ' + list[i])
});
}
return result;
}
(function() {
var fnlist = buildList([1, 2, 3]);
for (var i = 0; i < fnlist.length; i++) {
fnlist[i]();
}
})();
多快好省!前端后端,线上线下,名师精讲
更多了解 加: