0

I made a mistake in the code below. In a variable "x", I stored one character from a string "s". Then, I mistakenly incremented "x" which caused the error given after the code. Why does JS allow me to increment a character variable in the first place ? How do I prevent such errors from happening ?

function jsFun(s){
    var x = s.charAt(0);
    s++;//Wrong !
    x = s.charAt(1);
    return x;
}

console.log(jsFun("one"));

Error : In line 4.

TypeError: s.charAt is not a function
E_net4
  • 27,810
  • 13
  • 101
  • 139
MasterJoe
  • 2,103
  • 5
  • 32
  • 58
  • 2
    what is the purpose of the `s++`? This is causing the error because it only makes sense for numbers (so JS, in its "helpful" way, is coercing `s` to be a number on that line). – Robin Zigmond Jun 09 '20 at 23:19
  • @RobinZigmond - This code is just a snippet from much bigger code in which two variables had similar names - s and sId. I had to increment sId, but I mistakenly incremented s instead. Is there a term for the "coercion" ? I will google that term to learn more. – MasterJoe Jun 09 '20 at 23:24
  • 2
    Coercion is the general term for when JS automatically converts a variable to a different type. – Robin Zigmond Jun 09 '20 at 23:28
  • @RobinZigmond - I searched coercion javascript. The formal name for this is Type Coercion. – MasterJoe Jun 09 '20 at 23:29
  • `s` is not a number type and can't be incremented – Mister Jojo Jun 09 '20 at 23:29
  • @MisterJojo - Yes, I have clearly mentioned that in my question. I wanted to know the reason why JS allows it. – MasterJoe Jun 09 '20 at 23:30
  • **again** in your function `jsFun` `s` is the argument and it is not a number type and can't be incremented – Mister Jojo Jun 09 '20 at 23:33
  • 1
    @masterjoe2 Javascript is a weakly typed language, meaning that many strange operations are "valid" and won't cause errors directly. For example you can sum a string and a number but can't subtract. – Elias Soares Jun 09 '20 at 23:33
  • @MisterJojo - Yes. You keep repeating the same thing. The answer I was looking for is "Type Coercion". Please see the comment by Robin Zigmond. – MasterJoe Jun 09 '20 at 23:33
  • I perfectly know what is type coercion in javascript, making your incrémentation on `s` is exactly the case – Mister Jojo Jun 09 '20 at 23:40
  • your `s++` transform the `s` argument in a number (NaN in reality) ==> this is the type coercion, then the string method `.charAt()` can't be applied to a number (or a NaN) and make your error – Mister Jojo Jun 09 '20 at 23:53

2 Answers2

5

Because the ECMAScript Language Specification allows it https://www.ecma-international.org/ecma-262/5.1/#sec-11.4.4.

The only time the ++ unary operator would throw a SyntaxError is if all the following are true:

  • Type(expr) is Reference is true
  • IsStrictReference(expr) is true
  • Type(GetBase(expr)) is Environment Record
  • GetReferencedName(expr) is either "eval" or "arguments"

Otherwise, it will try to parse the value into a number and increase it by one. A string does not meet the throwing criteria, so it gets parsed to a number (resulting in NaN in your example) and then, after increasing its value by 1, it still returns NaN.

If the string was numeric such as "1234", you would see that it gets turned into a number and increased by one, as you would expect with a number. Once you try to call the charAt function, however, your code would error out, since numbers do not have that function.

To prevent this behaviour using plain Javascript, you could check whether the variable is a non-NaN number before increasing it

if (!Number.isNaN(s)) {
   s++
}

You could also use isNaN if you would like to verify is the string is numeric-ish.

Also, like other answers said, you could use a type-checked alternative such as Typescript or a static type checker such as flow.js to prevent these errors at compile time.

Alberto Rivera
  • 3,652
  • 3
  • 19
  • 33
2

As some have mentioned JavaScript will let you do this because is weakly typed. Here is a good post about it - https://stackoverflow.com/a/964926/8161471

How can you prevent it? There are tools you can use like extensions with your editor that will highlight such problems as you work on your code. TypeScript, a superset of JavaScript, is another good alternative which can give you a more strongly type approach that looks a lot like C#/Java. What is TypeScript and why would I use it in place of JavaScript?.

Alejandro
  • 413
  • 3
  • 9