2

I has been view some topic about Operator Not Working, but cannot solve my problem.

I have 2 JavaScript code.

<span id="number">this work</span>
<span id="miaonumber">this doesn't work</span>
<script>
    setTimeout(start, 1000);

    var hh = 9999.9999;
    var num = document.getElementById('number');

    function start() {
        setInterval(increase, 1000);
        }

    function increase() {
        if (hh > 0.0001) {
            hh = (hh-0.0001).toFixed(15);
            num.innerText = hh;
        }
    }

    setTimeout(startmiao, 1000);

    var zz = 8888.8888;
    var nummiao = document.getElementById('miaonumber');

    function startmiao() {
        setInterval(increasemiao, 1000);
    }

    function increasemiao() {
        if (zz > 0) {
            zz = (zz+0.0001).toFixed(15);
            nummiao.innerText = zz;
        }
    }
</script>

The <span id="number"></span> will work, but the <span id="miaonumber"></span> doesn't work, I open F12 to view, every second +1 error Uncaught TypeError: (zz + 0.0001).toFixed is not a function

Andy G
  • 19,232
  • 5
  • 47
  • 69
Swee Hong
  • 539
  • 2
  • 12
  • 2
    If you use `+` with a string and a number, the result is a string, not a number. Strings don't have `toFixed`. You'll need to ensure that `zz` is a number (it isn't once you've assigned the result of `toFixed` to it), [in any of the many ways you can do that](https://stackoverflow.com/a/48227674/157247). – T.J. Crowder Jan 15 '18 at 11:57
  • I would also describe the fact that using subtraction coerces the value to a number, whereas addition (concatenation) doesn't. That is why the first version works and the second doesn't. Neither of the current answers mention this. – Andy G Jan 15 '18 at 12:03

3 Answers3

4

You're converting both hh and zz to strings when you use .toFixed(). If you keep them as numbers then they both work. Simply move the .toFixed() to where you set the element text.

setTimeout(start, 1000);

var hh = 9999.9999;
var num = document.getElementById('number');

function start() {
    setInterval(increase, 1000);
    }

function increase() {
    if (hh > 0.0001) {
        hh = hh - 0.0001;
        num.innerText = hh.toFixed(15);
    }
}

setTimeout(startmiao, 1000);

var zz = 8888.8888;
var nummiao = document.getElementById('miaonumber');

function startmiao() {
    setInterval(increasemiao, 1000);
}

function increasemiao() {
    if (zz > 0) {
        zz = zz + 0.0001;
        nummiao.innerText = zz.toFixed(15);
    }
}
<span id="number">this work</span><br />
<span id="miaonumber">this doesn't work</span>

Javascript is sensible enough to know that when you subtract values it's most likely that you want them to be numbers, so "123" - 1 == 122, but when you try to add it assumes you want to append to an existing string, so "123" + 1 == "1231"

Reinstate Monica Cellio
  • 25,975
  • 6
  • 51
  • 67
0

The problem is, you have a number and convert it to a string and the you assign it to zz again. Then you add a number, but while zz is a string, you get a string and string does not has the method toString.

Solution: Assign the stringed value only to the output and not to zz.

function start() {
    setInterval(increase, 1000);
}

function increase() {
    if (hh > 0.0001) {
        hh = (hh - 0.0001).toFixed(15);
        num.innerText = hh;
    }
}

function startmiao() {
    setInterval(increasemiao, 1000);
}

function increasemiao() {
    if (zz > 0) {
        zz += 0.0001;
        nummiao.innerText = zz.toFixed(15);
    }
}

var hh = 9999.9999,
    num = document.getElementById('number'),
    zz = 8888.8888,
    nummiao = document.getElementById('miaonumber');

setTimeout(start, 1000);
setTimeout(startmiao, 1000);
<span id="number">this work</span>
<span id="miaonumber">this doesn't work</span>
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
0

toFixed obtains a string value from a numeric value. When you then attempt to use + with this string value it defaults to concatenating text, rather than addition. This new text no longer has a toFixed method.

Use toFixed only when displaying the value(s), so that zz remains a number:

function increasemiao() {
    if (zz > 0) {
        zz = (zz+0.0001);
        nummiao.innerText = zz.toFixed(15);
    }
}

(This is also why it works initially, with 8888.8889, but fails on subsequent iterations.)

The first version works because subtraction (rather than addition/concatenation) coerces a value to a number.

Andy G
  • 19,232
  • 5
  • 47
  • 69