1
\$\begingroup\$

The function checks whether an array is of a specific type (only contains elements of that type), the types the function accepts for checking is basically all the JavaScript types plus any types that the user may define manually (using a constructor).

What would you do to make the function more sophisticated? What would you remove or add? How would you improve or extend the function?

const checkArrayType = function checkArrayType(arr, type) {
 
 if (!Array.isArray(arr)) {
 throw new Error('The argument "arr" must be an array!');
 }
 else if (type !== null && type !== undefined && typeof type != 'function') {
 throw new Error('The argument "type" must be a function, "null", or "undefined"!');
 }
 
 // 'null' and 'undefined' require a different check than the main one
 if (type === null || type === undefined) {
 return arr.every(function(e){
 return e === type;
 });
 }
 
 return arr.every(function(e){
 /* 
 * not using 'instanceof' because it would return 'true'
 * for cases like 'subObj instanceof Object'. 
 * ---------------------------------
 * using 'Object(e)' so that the check works for primitives, see:
 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object
 */
 return Object.getPrototypeOf(Object(e)) === type.prototype;
 });
 
};
console.log(checkArrayType([1,2,3,4], Number)); // true
console.log(checkArrayType(['hello', 10], String)); // false
console.log(checkArrayType([[1, 2.5], ['a', 'b']], Array)); // true
console.log(checkArrayType([null, null, null, null], null)); // true
console.log(checkArrayType([new String('hello'), new String('world')], Object)); // false
var Foo = function Foo(){};
console.log(checkArrayType([new Foo(), new Foo()], Foo)); // true
console.log(checkArrayType({a: null}, null)); // throws error
console.log(checkArrayType([], 'abc')); // throws error

One more thing, how am I supposed to deal with long comments like the one in this snippet ?

Martin R
24.2k2 gold badges37 silver badges95 bronze badges
asked Jan 1, 2018 at 20:17
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Maybe an optional parameter that if true will check if an item can be cast to the given type. For example, "1234" isn't a number, but could be cast to one without an error. \$\endgroup\$ Commented Jan 2, 2018 at 0:56
  • 2
    \$\begingroup\$ I have rolled back the last edit. Please see What to do when someone answers . \$\endgroup\$ Commented Jan 2, 2018 at 8:57

2 Answers 2

3
\$\begingroup\$

The implementation could be written more compactly using arrow functions, for example:

if (type === null || type === undefined) {
 return arr.every(e => e === type);
}
return arr.every(e => Object.getPrototypeOf(Object(e)) === type.prototype);

There are two arr.every calls at different execution paths. You could eliminate that duplicated logic by extracting the function parameter of arr.every to a variable:

var checker;
if (type === null || type === undefined) {
 checker = e => e === type;
} else {
 checker = e => Object.getPrototypeOf(Object(e)) === type.prototype;
}
return arr.every(checker);
answered Jan 1, 2018 at 21:44
\$\endgroup\$
4
  • \$\begingroup\$ Thanks for answering! Why arrow functions if you are not using this though ? \$\endgroup\$ Commented Jan 2, 2018 at 8:38
  • 1
    \$\begingroup\$ @Taurus arrow functions are especially appropriate when you're not using this. They are best with pure functions with no state. \$\endgroup\$ Commented Jan 2, 2018 at 8:45
  • \$\begingroup\$ A bit of a general question, don't you think !== is more straightforward and readable than === ? I don't know but to my brain it seems that way. \$\endgroup\$ Commented Jan 2, 2018 at 8:54
  • 1
    \$\begingroup\$ @Taurus I've never felt readability issues with these operators. But depending on the conditions used, there are sometimes readability aspects when choosing between some complex condition and its negated version, applying DeMorgan's Law, and arranging if and else statements. \$\endgroup\$ Commented Jan 2, 2018 at 9:09
1
\$\begingroup\$

The function does one thing well. I would change nothing. Wait for your calling code to develop a need for fancier functionality, and develop a (related) fancier function then.

The console.log() calls, with comments suggesting true return is expected, would benefit from being placed within a unit test framework.

You asked about the long comment. Delete the "----" ascii art. Prefer full sentences to sentence fragments. And for http://very-very-very-long.com/urls consider introducing them with a bit.ly shortened URL. Then there's something for a person to copy-n-paste / click on, and verify they landed in the expected place, while also giving you the flexibility to line wrap it, and defending against link rot as the months go by.

answered Jan 1, 2018 at 20:46
\$\endgroup\$
2
  • \$\begingroup\$ I thought that was an actual website for a while. How do they protect from link rot though ? \$\endgroup\$ Commented Jan 1, 2018 at 21:00
  • 1
    \$\begingroup\$ Link rot is a fact of life; pages (and sites) go 404 all the time. Half-life is on the order of eight months, with some folks (like NYTimes) being much better at URL-naming and archival storage than other folks. It is the responsibility of a comment's author to protect against link rot, by offering full citation, giving short (convenient, clickable) URL plus full (line wrapped) URL. The trouble with offering just a shortened URL is the target site might delete the page and 301 to another page, rather than correctly 404'ing the deleted page. Your 87-character URL can be hard to linewrap nicely. \$\endgroup\$ Commented Jan 1, 2018 at 21:11

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.