4

Snippet from underscore.js for testing object

_.isObject = function(obj) {
    return obj === Object(obj);
  };

What exactly is this doing that makes it check for the type?

A jsperf shows that this is faster than using a conventional check, that is why it is used.

3 Answers3

5

The Object constructor creates an object wrapper for the given value. If the value is null or undefined, it will create and return an empty object, otherwise, it will return an object of a type that corresponds to the given value.

Source

bfavaretto
  • 71,580
  • 16
  • 111
  • 150
Ricardo Alvaro Lohmann
  • 26,031
  • 7
  • 82
  • 82
1

I can't find the relevant documentation, but it appears that the Object function either returns a new object that wraps the passed in value or returns the argument if it's already an object; otherwise, the === test would always return false.

Object(5) === 5         // false, Object(5) creates Number object
Object(null) === null   // false, Object(null) creates an empty object

var foo = { prop: 'value' };
Object(foo) === foo     // true!? Argument is not wrapped

It appears that this behavior works to test if a value is an object.

Update

It appears that this is in the spec:

When the Object function is called with no arguments or with one argument value, the following steps are taken:
1. If value is null, undefined or not supplied, create and return a new Object object exactly as if the standard built-in Object constructor had been called with the same arguments (15.2.2.1).
2. Return ToObject(value).

And ToObject's "result is the input object" is also defined in the spec.

Jacob
  • 77,566
  • 24
  • 149
  • 228
1

What does Object(obj) do?

Read the EcmaScript spec on The Object Constructor Called as a Function and the abstract ToObject operation.

What exactly is this doing that makes it check for the type?

Object(obj) will only yield an object that is strictly equal (===) to obj (i.e the same reference as the input) when the input was a non-primitive value (null, booleans, strings, numbers, undefined), i.e. an EcmaScript Object (including String/Boolean/Number/Array instances, functions, other objects).

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Since the opposite of "primitive value" is "object", there's no reason in inverting the name :-) – Bergi Apr 13 '13 at 19:19
  • What is wrong with that fiddle, did you expect something to work different than it does? – Bergi Apr 13 '13 at 20:12
  • No, I'm not :-) We're not talking about object *literals* (as they appear in source code), but about *objects* which they might represent. Btw, we're neither talking about `Object.prototype.toString` and the internal [[class]] value of objects, nor about the Java language. If you are seeing objects as "reference type" and primitives as "value types", it sounds fine. – Bergi Apr 15 '13 at 17:47
  • No, every plain object (like `new MyConstructor`) will have `[object Object]`. The only exceptions are primitive-wrappers, `Array`s, `RegExp`s, and similar native/host objects. Still, all of them *are **objects*** - they are structures that can hold properties! And `typeof` has hardly anything to do with this question. – Bergi Apr 15 '13 at 18:16