Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does adding a property to an object literal's prototype change its "type"?

Tags:

So I have a simple isPlainObject method that I use to test for JavaScript object literals:

var isPlainObject = function (obj) {
  return typeof obj === "object" && {}.toString.call(obj) === "[object Object]";
};

Now I have a plain object:

var obj = {'one': 1, 'two': 2, 'three': 3};

When I run it through the isPlainObject(obj) function it works as expected and returns true. My question arrives from adding a property to the object's prototype:

obj.constructor.prototype.four = 4;

Now when I run isPlainObject(obj) on obj it returns false. typeof obj returns object in both instances. The toString returns [object Number] in the second instance after I've added a property to the prototype.

What exactly has happened to change obj? What's going on?

EDIT: This only happens when tested within the confines of a QUnit function call.

test("each", function() {

    _.each([1, 2, 3], function(i,v) {
      equal(v, i + 1, 'each iterator provided index and value from array');
    });

    var obj = {'one': 1, 'two': 2, 'three': 3};
    console.log(_.isPlainObject(obj)); // => true
    obj.constructor.prototype.four = 4;
    console.log(_.isPlainObject(obj)); // => false

});

EDIT: This is the console.log I get when logging the arguments array-like object within isPlainObject.

Logging out the <code>arguments</code> object

Looking at the log would seem to indicate the array now has two arguments. But the length still reads 1.