首页 > 这是一段JS函数,其中有一些不明白的地方

这是一段JS函数,其中有一些不明白的地方

今天在查看网上淡入淡出的轮播原代码时,有一些不明白的地方

function addEvent(){
            for(var i=0;i<otxtLen;i++){
                (function(_i){
                    oBtn[_i].onclick=function(){
                        clearTimeout(autoChange);
                        changeTo(_i);//这是调用开始轮播的变换函数
                        curIndex=_i;

                        autoChange=setInterval(function(){
                            if(curIndex<otxtLen-1){
                                curIndex++;
                            }
                            else{
                                curIndex=0;
                            }
                            changeTo(curIndex);
                        },2500);
                    }

                })(i);
            }
        }

问题1:
这个(_i)传进去的值是for循环的i吗?
我试着把(_i)改成(i),运行起来也是没有问题。

问题2:
什么for循环里面的function要用圆括号包起来?结尾有一个(i)是做什么用的呢?

问题3:
代码中clearTimeout(autoChange);为什么setInterval可以用clearTimeout来关闭?

麻烦各位朋友帮忙解决下小弟的困惑,万分感谢!!!


我有个疑问,这里的autoChange是不是会提升为全局变量?


问题1
行为是一样的, 因为每次循环时的匿名函数都是新的scope, 不影响for那个scope中的变量i. 专门用不同的变量名可能是为了好读.

问题2
(function(){})(i)是函数调用, 这种定义一个匿名函数然后立刻调用的写法叫IIFE.
IIFE经常是为了创建scope, 即把每次循环时i的绑定到一个新的变量: 每次创建的匿名函数都有一个_i变量, 这个_i的值固定为匿名函数创建时的i的值. 就算i后来变掉也没影响.

问题3
我也不知道为什么...标准好像不应该可以这样做, 不过有的浏览器中clearInterval和clearTimout真的可以互换.


  1. _i是函数的形参

  2. 这是for循环中的经典闭包,后面的(i)是实参

  3. 个人认为是错的,应该是clearInterval。具体是否可以用clearTimeout来替代,不确定。


問題1 _i 是 for 的 i 帶入的沒錯不過更嚴格地說是 IIFE 立即函式就下面那個 i 傳入的,_i 應該是為了避免疑義。

問題2

思考一下下面這個簡化的例子

var funcs = [];
for (var i = 0; i < 10; i++) {
  funcs[i] = function () {
    console.log(i); // 當你的 event 需要 i 時
  }
}

funcs[0](); // 預計是 0 但輸出是 10
var funcs = [];
for (var i = 0; i < 10; i++) {
  (function (i) {
    funcs[i] = function () {
      console.log(i); // 當你的 event 需要 i 時
    }
  })(i);
}

funcs[0](); // 就是 0 了

原理就是利用閉包去保留 context 我推薦這篇寫的挺詳細的。

問題3

參考這篇

第二則回答從 w3c 定義推論出他們是一樣的。可以視為同意。
不過我暫時比較接受第一個答案不應該互通,不過事實是大部分瀏覽器實作上是共用 timer 清除,所以可把它們視為同意,但不該認為兩者就沒有差別。

看看w3c自己的範例都用了(搜尋 clearTimout 看範例)我能說什麼呢!?


最典型的闭包问题,可以看看阮一峰或者司徒正美的文章,举得都是这种例子,如果你不用闭包实现的话,这里不同按钮上绑定的函数在点击后调用的函数中i为同一个值,明显不是本意。

【热门文章】
【热门文章】