You could simplify the code a bit and return null if there's no more than one iteration to check the prefix. Also you could add an extra check for empty or 1 word arrays, otherwise your code would fail.

function prefix(words) {
    if(words.length < 2 || words[0] === '') { // extra check for 0 or 1 words
      return words[0] || null;
    }
    let i = 0;
    while (true) {
        const c = words[0][i];
        for (let j = 1; j < words.length; j++) {
            if (c != words[j][i]) {
                return i ? words[0].slice(0, i) : null;
            }
        }
        i++; // this will happen when at least 1 character is common
    }
}
console.log(prefix([]));
console.log(prefix(['']));
console.log(prefix(['', '']));
console.log(prefix(['flower', '']));
console.log(prefix(['flower']));
console.log(prefix(["flower", "flowers", "floyd", "flow", "floor"]))
console.log(prefix(["flower", "flowers", "floyd", "flow", "sunflower", "floor"]))

And a benchmark:

<script benchmark data-count="10000000">

const words = ["flower", "flowers", "floyd", "flow", "floor"];

// @benchmark museum/tom
    function prefix(words) {
      for (let i = 0; i < words[0].length; i++) {
        const char = words[0][i];
        for (let j = 1; j < words.length; j++) {
          // first letter unequal
          if (i === 0 && words[j][i] !== char) {
            return null;
          }
          if (i === words[j].length || words[j][i] !== char) {
            return words[0].substring(0, i);
          } 
        }
      }
      // No common prefix found
      return null;
    }
    // @run
    prefix(words);

// @benchmark Alexander
    function prefix2(words) {
        if(words.length < 2 || words[0] === '') { // extra check for 0 or 1 words
          return words[0] || null;
        }
        let i = 0;
        while (true) {
            const c = words[0][i];
            for (let j = 1; j < words.length; j++) {
                if (c != words[j][i]) {
                    return i ? words[0].slice(0, i) : null;
                }
            }
            i++;
        }
    }
    // @run
    prefix2(words);
</script>
<script src="https://cdn.jsdelivr.net/gh/silentmantra/benchmark/loader.js"></script>

Answer from Alexander Nenashev on Stack Overflow
Top answer
1 of 4
2

You could simplify the code a bit and return null if there's no more than one iteration to check the prefix. Also you could add an extra check for empty or 1 word arrays, otherwise your code would fail.

function prefix(words) {
    if(words.length < 2 || words[0] === '') { // extra check for 0 or 1 words
      return words[0] || null;
    }
    let i = 0;
    while (true) {
        const c = words[0][i];
        for (let j = 1; j < words.length; j++) {
            if (c != words[j][i]) {
                return i ? words[0].slice(0, i) : null;
            }
        }
        i++; // this will happen when at least 1 character is common
    }
}
console.log(prefix([]));
console.log(prefix(['']));
console.log(prefix(['', '']));
console.log(prefix(['flower', '']));
console.log(prefix(['flower']));
console.log(prefix(["flower", "flowers", "floyd", "flow", "floor"]))
console.log(prefix(["flower", "flowers", "floyd", "flow", "sunflower", "floor"]))

And a benchmark:

<script benchmark data-count="10000000">

const words = ["flower", "flowers", "floyd", "flow", "floor"];

// @benchmark museum/tom
    function prefix(words) {
      for (let i = 0; i < words[0].length; i++) {
        const char = words[0][i];
        for (let j = 1; j < words.length; j++) {
          // first letter unequal
          if (i === 0 && words[j][i] !== char) {
            return null;
          }
          if (i === words[j].length || words[j][i] !== char) {
            return words[0].substring(0, i);
          } 
        }
      }
      // No common prefix found
      return null;
    }
    // @run
    prefix(words);

// @benchmark Alexander
    function prefix2(words) {
        if(words.length < 2 || words[0] === '') { // extra check for 0 or 1 words
          return words[0] || null;
        }
        let i = 0;
        while (true) {
            const c = words[0][i];
            for (let j = 1; j < words.length; j++) {
                if (c != words[j][i]) {
                    return i ? words[0].slice(0, i) : null;
                }
            }
            i++;
        }
    }
    // @run
    prefix2(words);
</script>
<script src="https://cdn.jsdelivr.net/gh/silentmantra/benchmark/loader.js"></script>

2 of 4
0

Here's what's happening

In the case of ["flower", "flowers", "floyd", "flow", "sunflower", "floor"], the loop iterates through the characters of the first word and compares them to the other words.

When i reaches the length of the first word (i = 5), there is no exit condition for the outer loop, so it continues to the next iteration.

However, there's no corresponding character in the other words, so the inner loop conditions (i === words[j].length || words[j][i] !== char) are not met.

Since the loop completes without returning anything and all the words are not the same, the function ends without a return statement.

In JavaScript, when a function doesn't return anything, it returns undefined, and that's why you see nothing printed.

The fix for this is to add a return statement after the outer loop to handle the case where the loop completes without finding a common prefix.

function prefix(words) {
    /* Check if words list is 0, since prefix will always be null
    in this case */
    if (words.length === 0) return null; 

    for (let i = 0; i < words[0].length; i++) {
        const char = words[0][i];
        for (let j = 1; j < words.length; j++) {
            if (i === words[j].length || words[j][i] !== char) {
                if (i === 0) return null;
                return words[0].substring(0, i);
            }
        }
    }

    return null; // Add this line to handle the missing case
}

console.log(
    prefix(['flower', 'flowers', 'floyd', 'flow', 'flinging', 'floor'])
); // output: null

console.log(
    prefix(['triangle', 'trick', 'trivial', 'triceratops', 'tricycle']) // output: 'tri'
);

Top answer
1 of 3
8

TL;DR

Assuming we only need to apply a straight forward modification, I would avoid too much syntactical sugar and just write it this way:

function divide(num1, num2) {
  if (arguments.length < 2) {
    return null;
  }
  return num1/num2;
}

If we want to make it simple and elegant, I would write it this way (requires ES6 features):

const divide = (...args) => args.length < 2 ? null : args[0] / args[1];

Explanation

Improvement steps in vanilla JS (ES5 and before)

  • Using function arguments: this is simply an array like object that will magically appear inside your function, which contains the arguments you have passed to the function.

function divide(num1, num2) {
  if (arguments.length < 2) {
    return null;
  }
  return num1/num2;
}

While this is a great solution for the problem there are a downsides to it, if you wanted to switch to arrow function arguments object doesn't appear.

  • **Using ternary operator**you can farther more reduce the code by using the ternary ? which is best suitable for simple if statements

function divide(num1,num2) {
  return arguments.length < 2 ? null : num1 / num2;
}

Improvement steps in ES6

  • Using spread (in this case it is actually called rest): the ... can be used to either collect items into an array known as rest, or expand an array known as spread.

function divide(...args) {
  return args.length < 2 ? null : args[0] / args[1];
}

JavaScript will collect all the arguments passed to the function and put them into an array called args, I like this better since the reader can see where is args defined.

  • using arrow function: there are many difference between arrow and normal function, but many prefer it since it is shorter, and since we have a one-liner function why not use it.

const divide = (...args) => args.length < 2 ? null : args[0] / args[1];

On a final note all the previous solutions has a downside that we are only checking for length of arguments but not contents of arguments, lets assume that someone sent undefined into one of the first two arguments, you'll have 2 arguments but one of them is kinda missing and you'll get NaN since number of arguments is 2.

function divide(num1, num2) {
	  if (num1 === undefined || num2 === undefined) {
return null;
  }
  return num1/num2;
}

Demo

function divide1(num1, num2) {
	  if (arguments.length < 2) {
	    return null;
	  }
	  return num1/num2;
	}
	
function divide2(num1,num2) {
	  return arguments.length < 2 ? null : num1 / num2;
	}
	
	
function divide3(...args) {
	  return args.length < 2 ? null : args[0] / args[1];
	}


const divide4 = (...args) => args.length < 2 ? null : args[0] / args[1];


const test = (cb) => {
  console.log("-------->" + cb.name)
  console.log(cb());
  console.log(cb(1));
  console.log(cb(1, 2));
  console.log(cb(1, undefined));
  console.log(cb(1, null));
  console.log(cb(1, 2, 3));
};

test(divide1);
test(divide2);
test(divide3);
test(divide4);

2 of 3
2

Peep this.

function divide(num1, num2) {
    if(arguments.length < 2) return null;
    return num1 / num2;
}

The arguments object is available in all (non-arrow) function and represents all the arguments passed into the function. It has a length property that tells you how many arguments there are.

Discussions

arrays - How to return null in JavaScript? - Stack Overflow
Does anyone help me to solve the "Days Of The Week Exercise" in JavaScript? I searched MDN and tried many times as much as I can, but I still don't get what the null is, and how to use nu... More on stackoverflow.com
🌐 stackoverflow.com
Is it better to return `undefined` or `null` from a javascript function? - Stack Overflow
That being said, a special value ... I can return for this input") is required and this for me is null not undefined. ... You can see some support for this argument in some other typed languages as well where termination without meaningful result are expressed using an option type (sometimes also referred to as nullable type). An example for this is is Maybe in Haskell. On the other hand, we of course do not know what undefined in JavaScript is really ... More on stackoverflow.com
🌐 stackoverflow.com
NULL vs undefined as explicit return typ
Nobody seems to agree on this. In my opinion having two values for null is dumb. I’d like to only have one value that represents a null value. Since it’s not possible to avoid using undefined, I avoid using null instead. There’s an eslint rule that you can use that will give an error every time null is used. That’s the best solution IMO More on reddit.com
🌐 r/typescript
11
8
July 13, 2023
Should I return null or an empty object?
That depends on whether you consider not finding the file an error - then return null - or if you want to have a list of all nodes matching your pattern no matter whether a file exists - then return an empty object. More on reddit.com
🌐 r/AskProgramming
16
9
July 25, 2023
🌐
MDN Web Docs
developer.mozilla.org › en-US › docs › Web › JavaScript › Reference › Operators › null
null - JavaScript - MDN Web Docs
The null keyword refers to the null primitive value, which represents the intentional absence of any object value. function getVowels(str) { const m = str.match(/[aeiou]/gi); if (m === null) { return 0; } return m.length; } console.log(getVowels("sky")); // Expected output: 0
🌐
JavaScript Tutorial
javascripttutorial.net › home › an essential guide to javascript null
An Essential Guide to JavaScript null
September 29, 2020 - const square = null; if (square) { console.log('The square is not null'); } else { console.log('The square is null'); }Code language: JavaScript (javascript) ... In this example, the square variable is null therefore the if statement evaluates it to false and executes the statement in the else clause. The typeof value returns the type of the value.
Top answer
1 of 12
183

Undefined typically refers to something which has not yet been assigned a value (yet). Null refers to something which definitively has no value. In that case, I would recommend returning a null. Note that a function with no specified return value implicitly returns undefined.

From the ECMAScript2015 spec

4.3.10 undefined value

primitive value used when a variable has not been assigned a value

4.3.12 null value

primitive value that represents the intentional absence of any object value

http://www.ecma-international.org/ecma-262/6.0/#sec-terms-and-definitions-undefined-type

Further reading:

When is null or undefined used in JavaScript?

2 of 12
88

I will give you my personal opinionated way of choosing between the two.

My simple question is: could the value, given another input/state/context be defined to something?

If the answer is yes then use null else use undefined. More generally any function returning an object should return null when the intended object does not exist. Because it could exist given another input/state/context.

null represents the absence of value for a given input/state/context. It implicitly means that the concept of the value itself exist in the context of your application but may be absent. In your example the concept of a next card exists but the card itself may not exist. null should be used.

undefined implicitly represents the absence of meaning of that value in your application's context. For example, if I manipulate a user object with a given set of properties and I try to access the property pikatchu. The value of this property should be set to undefined because in my context it doesn't make any sense to have such a property.

🌐
Laracasts
laracasts.com › discuss › channels › javascript › how-to-return-null-instead-of-undefined-using-find
How to return null instead of undefined using .find()
[0, 1, 2, 3].find((num) => num % 2 === 0) || null // result is null, not 0! ... Please sign in or create an account to participate in this conversation.
Find elsewhere
🌐
Dmitri Pavlutin
dmitripavlutin.com › javascript-null
Everything about null in JavaScript - Dmitri Pavlutin
In this post, you'll learn everything about null in JavaScript: its meaning, how to detect it, the difference between null and undefined, and why using null extensively creates code maintenance difficulties. ... If you see null (either assigned to a variable or returned by a function), then at that place should have been an object, but for some reason, an object wasn't created.
🌐
Medium
vvkchandra.medium.com › essential-javascript-mastering-null-vs-undefined-66f62c65d16b
Essential JavaScript: Mastering null vs undefined | by Chandra Gundamaraju | Medium
September 9, 2020 - In the above snippet, user1.email doesn’t even exist while user2.email exists with an undefined value. When we use user1.email and user2.email, there is no easy to way distinguish between whether it exists or not. You will have to use hasOwnProperty or some other mechanism. user3.email is explicitly set to null. So we can always guarantee that it exists. Same goes for arrays as well. function returning null As we already learned, every function returns undefined when no other value is returned from that function.
🌐
Reddit
reddit.com › r/askprogramming › should i return null or an empty object?
r/AskProgramming on Reddit: Should I return null or an empty object?
July 25, 2023 -

My company uses files that are essentially merged XML files into one. I wrote a pretty basic parser and node object that contains the tag name, text, and child node objects. Recently I ran into an error where the file couldn't be found, and my function that searches for child nodes returned null (as it should). But it caused a runtime error, so I'm trying to figure out the best way to address issue. Should I return an empty object so that the code doesn't crash, or should I continue returning null and wrap it in a try/catch?

🌐
GeeksforGeeks
geeksforgeeks.org › null-in-javascript
Null in JavaScript | GeeksforGeeks
June 5, 2024 - In the first scenario, we create variableOne that creates a new object of Square, and a value of 10 is passed in the create_function() method. In the second scenario, we have created variableTwo but we do not pass anything there and therefore it returns a null as output. Another example that will illustrate Null in JavaScript.
🌐
freeCodeCamp
forum.freecodecamp.org › t › javascript-returns-null-somehow-works-on-codecamp › 421389
Javascript returns Null (somehow works on codecamp) - The freeCodeCamp Forum
September 18, 2020 - Hey there, i’ve started an small JavaScript course before getting into the freecodecamp one (would like to get some quick principles first). I’m trying to store the .innerHtml on a variable to restore it later; it’s working fine while using codepen; but when i take it to atom it won’t work.
🌐
Codecademy
codecademy.com › forum_questions › 50735705d9609d000201ca83
Why is my function returning null? | Codecademy
Because at that point the value of nightSurcharge is null, it means that the value of cost becomes null. You need to move var cost = ... so that it comes after var nightSurcharge = ... The final thing is that because nightSurcharge is a function that expects an input of an hourOfDay parameter, when you call it to calculate the value of cost you need to make sure you give it that input.
Top answer
1 of 1
1

You can eventually do it by parsing the ECMAScript Language Specification which conviniently provides the implementation of the native methods.

For instance, Object.defineProperty(O, P, Attributes) is documented like this:

  1. If Type(O) is not Object, throw a TypeError exception.
  2. Let key be ? ToPropertyKey(P).
  3. Let desc be ? ToPropertyDescriptor(Attributes).
  4. Perform ? DefinePropertyOrThrow(O, key, desc).
  5. Return O.

Here, simply by parsing the list, you can determine that:

  • The method actually returns something, because one of the elements from the list matches the Return .*\. pattern.

  • The method returns the parameter O, because O is among the arguments of the method.

Similarly, Array.prototype.find very conviniently tells you that sometimes, the method:

  1. Return[s] undefined.

The difficulty is that even this simplest example isn't easy to perform programmatcially. I suppose that while ECMAScript is very consistent in its descriptions of the methods, the high number of possible forms of those methods make any parsing of the documentation rather complex. For instance, Array.prototype.join returns R, but R is not an argument: instead, it is a value which is assigned through the statements such as:

  1. If element0 is undefined or null, let R be the empty String; otherwise, let R be ? ToString(element0).

Unless there is an actual BNF grammar that was used to write the spec, parsing such statements would be difficult to impossible.

The good side, however, is that if you achieve to create such parser, it will include the “edge cases, including functions used improperly” you were talking about.

My use case that inspired my question was coding a "maybe" monad that would need to deal with null or undefined coming from any source, and I was just interested in creating a few different demo functions that would do so.

In my humble opinion, creating the list of all JavaScript methods just to have “a few different demo functions” is an overkill. Why not limiting yourself by one or several methods and to use them as a demo?

Still using the spec, an example of a method which returns undefined is Array.prototype.find already listed above; for null, an example could be Date.prototype.toJSON.

🌐
MDN Web Docs
developer.mozilla.org › en-US › docs › Web › JavaScript › Reference › Global_Objects › null
null - JavaScript | MDN
May 23, 2022 - The null keyword refers to the null primitive value, which represents the intentional absence of any object value. function getVowels(str) { const m = str.match(/[aeiou]/gi); if (m === null) { return 0; } return m.length; } console.log(getVowels("sky")); // Expected output: 0
🌐
Medium
tactician.medium.com › why-you-should-not-return-null-in-js-b47028eb641c
Why you should not return null in JS | by Joshua Aguilar | Medium
April 7, 2023 - Hard checking for a null value using the === or !== operator can also be an anti-pattern in JavaScript. This is because JavaScript has a concept of "falsy" values, which includes not only null, but also undefined, 0, NaN, and an empty string ...