Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why I'm not getting an error when checking the length of null [duplicate]

I'm checking the number of digits in a string using the match and length properties. Here is the codepen with my function http://codepen.io/PiotrBerebecki/pen/redMLE

Initially when returning numberOfDigits.length I was getting an error message (Cannot read property 'length' of null). I've solved this issue by changing the line to (numberOfDigits && numberOfDigits.length). This works but I would like to get a better understanding why the new statement can be executed now. Does the interpreter execute the `numberOfDigits.length now?

Also, why are we getting the same errors when the operands are reversed (numberOfDigits.length && numberOfDigits)?

Here is the full JavaScript code:

function checkLength(str) {
  let numberOfDigits = str.match(/\d/g);
  return (numberOfDigits && numberOfDigits.length);
}

console.log(  checkLength('T3xt w1th sOme numb3rs')  );
console.log(  checkLength('Text with some numbers')  );

UPDATE 1: The answers below explained that:

  • The order of the operands in the && expression counts.
  • JavaScript optimises the && operator and if the first operand evaluates to null then JavaScript does not check the second one as the expression cannot evaluate to nothing else than null / false.
like image 278
Piotr Berebecki Avatar asked Apr 13 '16 14:04

Piotr Berebecki


People also ask

How do you write not equal to null in JavaScript?

Use the strict inequality (! ==) operator to check if a variable is not null, e.g. myVar !== null . The strict inequality operator will return true if the variable is not equal to null and false otherwise.

Is NULL a data type in JavaScript?

In JavaScript null is "nothing". It is supposed to be something that doesn't exist. Unfortunately, in JavaScript, the data type of null is an object.


2 Answers

JavaScript tries to optimise the && operator:

numberOfDigits && numberOfDigits.length

If numberOfDigits is a falsy value (and null is falsy), then the entire expression will be falsy and there is no need to evaluate numberOfDigits.length.

Falsy values are: undefined, null, 0, '', false, NaN. One way to check if something is falsy is to use the Boolean(falsyValue) === false (or more practical but less verbose ! falsyValue).


This is a side effect of the && operator. I can recommend to avoid using it and transform the code to something readable:

function checkLength(str) {
  let numberOfDigits = str.match(/\d/g);
  return Array.isArray(numberOfDigits) ? numberOfDigits.length : 0;
}
like image 124
Dmitri Pavlutin Avatar answered Sep 22 '22 19:09

Dmitri Pavlutin


"Does the interpreter execute the `numberOfDigits.length now?"

No, JavaScript short-circuits logical expressions - as soon as result is known (i.e. first operand in and is falsy or first operand in or is truthy), no further operations are executed in the expression.

Docs: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators

also, beware: && and || do not necessarily return Booleans in JavaScript

like image 43
Tomasz Lewowski Avatar answered Sep 21 '22 19:09

Tomasz Lewowski