未捕获的TypeError:X不是函数。使用javascript闭包时

时间:2018-11-20 21:51:07

标签: javascript closures settimeout infinite-loop

我正在使用JavaScript,并且在控制台中看到以下错误:

  

未捕获的TypeError:div不是函数。

function getRandomColor() {
    var letters = '0123456789ABCDEF';
    var color = '#';
    for (var i = 0; i < 6; i++) {
        color += letters[Math.floor(Math.random() * 16)];
    }
    return color;
}

function createDiv(interval) {
    let radius = 300;
    let int = interval;
    var f = 0;
    var s = 2 * Math.PI / 180;
    let timerId = window.setTimeout(function tick()
    {
        var div = document.createElement('div');
        div.className = 'circle';
        div.style.backgroundColor = getRandomColor();
        div.style.left = (radius + radius * Math.cos(f)) + 'px';
        div.style.top = (radius + radius * Math.sin(f)) + 'px';
        document.body.appendChild(div);
        f += s;
        setTimeout(tick, int);
    }, int)

}

let div = createDiv(10);
div(); 

为简单起见,我留下了以下内容:

function createDiv(interval) {
    let timerId = window.setTimeout(function tick()
    {
        setTimeout(tick, 10);
    }, 10)
}

let div = createDiv(10);
div();

这本质上是一个无限循环。并且在调用div()时出现错误,但是循环正在工作。

怎么了?以及如何解决?

2 个答案:

答案 0 :(得分:2)

这里没有闭包:您正在调用一个返回undefined的函数,并试图像对待一个函数一样调用undefined()。只需像createDiv(10);这样调用您的函数即可。请注意,我已经为您的div添加了高度和宽度,以便可见结果。

function getRandomColor() {
  var letters = '0123456789ABCDEF';
  var color = '#';
  for (var i = 0; i < 6; i++) {
    color += letters[Math.floor(Math.random() * 16)];
  }
  return color;
}

function createDiv(interval) {
  let radius = 300;
  let int = interval;
  var f = 0;
  var s = 2 * Math.PI / 180;
  let timerId = window.setTimeout(function tick() {
    var div = document.createElement('div');
    div.className = 'circle';
    div.style.backgroundColor = getRandomColor();
    div.style.height = div.style.width = "50px";
    document.body.appendChild(div);
    f += s;
    setTimeout(tick, int);
  }, int)
}

createDiv(1000);

答案 1 :(得分:1)

function getRandomColor() {
    var letters = '0123456789ABCDEF';
    var color = '#';
    for (var i = 0; i < 6; i++) {
        color += letters[Math.floor(Math.random() * 16)];
    }
    return color;
}

function createDiv(interval) {
    let radius = 300;
    let int = interval;
    var f = 0;
    var s = 2 * Math.PI / 180;
    window.setTimeout(function tick()
    {
        var div = document.createElement('div');
        div.className = 'circle';
        div.style.backgroundColor = getRandomColor();
        div.style.left = (radius + radius * Math.cos(f)) + 'px';
        div.style.top = (radius + radius * Math.sin(f)) + 'px';
        document.body.appendChild(div);
        f += s;
        setTimeout(tick, int);
    }, int)

}

let div = createDiv(10);
console.log(div);
try {
  div();
} catch (err) {
  console.log('error')
}


function createDivSmall(interval) {
   window.setTimeout(function tick()
    {
        setTimeout(tick, interval);
    }, 10)
}

let divSmall = createDivSmall(10);
console.log(divSmall);
try {
  divSmall();
} catch (err) {
  console.log('Small error')
}

在您的createDiv函数中,您什么都不返回,因此默认行为是返回undefined。这将设置div = undefined。此时div不是函数,因此尝试调用它会引发错误。 createDiv正在为您启动循环并运行该循环,无需将变量设置为返回值。