0

Often while using JavaScript you run into silly problems. One such problems is discerning between Object types.

Is there a way to create a function with this functionality? See Below:

_discern = function () { [ function code ] };

_discern({}); // Logs: Object

_discern([]); // Logs: Array

_discern(document); // Logs: Pseudo-Object

_discern(document.querySelectorAll("*")); // Logs: Pseudo-Array

I've already tried creating a function that checks for array-likeness, but that didn't work as good as I had hoped:

isArrLike = function (_) {

    _[0] = 0; return [].slice.call(_).length >= Object.values(_).length;
};

And I've tried using that behavior into another function. All failures. Is there a way?

1
  • How do you define "pseudo-object"? Do you mean exotic object? There was a concept of host object, but it's been removed. A good start would be to provide an explicit definition of what tests or features define each type of object. Commented May 29, 2017 at 4:08

3 Answers 3

1

Looks like you want to know if something behaves like an array, instead of looking for the actual type/constructor.

If that's the case, it should be enough to check if something is iterable:

function isIterable(obj) {
  // checks for null and undefined
  if (obj == null) {
    return false;
  }
  return typeof obj[Symbol.iterator] === 'function';
}
Sign up to request clarification or add additional context in comments.

4 Comments

You're amazing.
What is your definition of "iterable"? Array methods work on any object with a length property, is that enough? Is a NodeList an "iterable"? It certainly is iterable. ;-)
@RobG Array methods DO NOT work on any object with a length property. E.g. arguments object of function. It has a length property and properties indexed from zero, but it doesn't have Array's built-in methods like forEach() and map()
@Experimenter— Array.prototype.call({length:1}, x => console.log(x)) works for me. And Array.prototype.forEach.call({length:1, 0:'blah'}, x => console.log(x)).
0

All of these are objects:

  • is array → return x instanceof Array or Array.isArray(x)
  • is function → return typeof x === 'function'
  • is HTML element → return x instanceof HTMLElement
  • is plain object → return typeof x === 'object' && /* ... is not array, not function, not HTML element */

1 Comment

x instanceof Array will fail across frames, x instanceof HTMLElement makes assumptions about the host environment that aren't necessarily supported, as does typeof x === 'object' not being an HTML element or some other host object (try them in IE).
0

Thanks to Logain's answer, I can solve the problem. Here's my approach:

kind = function (a) {

    let u = toString.call(a.valueOf()).slice(8, -1);

    if (a == null || u == "String" || u == "Number" || u == "Boolean") {

        return u;
    }

    else if (typeof a[Symbol.iterator] == "function") {

        return u != "Array" ? "Array-Like" : u;
    }

    else {

        return u;
    }
};

Comments

Your Answer

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.