Object
Object()
is a constructor that creates objects, for example:
> var o = new Object();
This is the same as using the object literal:
> var o = {}; // recommended
You can pass anything to the constructor and it will try to guess what it is and use a more appropriate constructor. For example, passing a string to new Object()
will be the same as using the new String()
constructor. This is not a recommended practice (it's better to be explicit than let guesses creep in), but still possible.
> var o = new Object('something'); > o.constructor; function String() { [native code] } > var o = new Object(123); > o.constructor; function Number() { [native code] }
All other objects, built-in or custom, inherit from Object
. So, the properties and methods listed in the following sections apply to all types of objects.
Members of the Object constructor
Have a look at the following table:
Property/method |
Description |
---|---|
|
The prototype of all objects (also an object itself). Anything you add to this prototype will be inherited by all other objects, so be careful. > var s = new String('noodles'); > Object.prototype.custom = 1; 1 > s.custom; 1 |
The Object.prototype members
Have a look at the following table:
Property/method |
Description |
---|---|
|
Points back to the constructor function used to create the object, in this case, > Object.prototype.constructor === Object; true > var o = new Object(); > o.constructor === Object; true |
|
Returns a string representation of the object. If the object happens to be a > var o = {prop: 1}; > o.toString(); "[object Object]" > var n = new Number(255); > n.toString(); "255" > n.toString(16); "ff" |
|
The same as In browsers, you can figure out the language using the property > navigator.language; "en-US " |
|
Returns a primitive representation of > var o = {}; > typeof o.valueOf(); "object" > o.valueOf() === o; true > var n = new Number(101); > typeof n.valueOf(); "number" > n.valueOf() === n; false > var d = new Date(); > typeof d.valueOf(); "number" > d.valueOf(); 1357840170137 |
|
Returns > var o = {prop: 1}; > o.hasOwnProperty('prop'); true > o.hasOwnProperty('toString'); false > o.hasOwnProperty('fromString'); false |
|
Returns > var s = new String(''); > Object.prototype.isPrototypeOf(s); true > String.prototype.isPrototypeOf(s); true > Array.prototype.isPrototypeOf(s); false |
|
Returns > var a = [1, 2, 3]; > a.propertyIsEnumerable('length'); false > a.propertyIsEnumerable(0); true |
ECMAScript 5 additions to Object
In ECMAScript 3 all object properties can be changed, added, or deleted at any time, except for a few built-in properties (for example, Math.PI
). In ES5 you have the ability to define properties that cannot be changed or deleted—a privilege previously reserved for built-ins. ES5 introduces the concept of property descriptors
that give you tighter control over the properties you define.
Think of a property descriptor as an object that specifies the features of a property. The syntax to describe these features is a regular object literal, so property descriptors have properties and methods of their own, but let's call them attributes to avoid confusion. The attributes are:
value
– what you get when you access the propertywritable
– can you change this propertyenumerable
– should it appear infor-in
loopsconfigurable
– can you delete itset()
– a function called any time you update the valueget()
– called when you access the value of the property
Further, there's a distinction between data descriptors
(you define the properties enumerable
, configurable
, value
, and writable
) and accessor descriptors
(you define enumerable
, configurable
, set()
, and get()
). If you define set()
or get()
, the descriptor is considered an accessor and attempting to define value or writable will raise an error.
Defining a regular old school ES3-style property:
var person = {}; person.legs = 2;
The same using an ES5 data descriptor:
var person = {}; Object.defineProperty(person, "legs", { value: 2, writable: true, configurable: true, enumerable: true });
The value of value
if set to undefined
by default, all others are false
. So, you need to set them to true
explicitly if you want to be able to change this property later.
Or, the same property using an ES5 accessor descriptor:
var person = {}; Object.defineProperty(person, "legs", { set: function (v) {this.value = v;}, get: function (v) {return this.value;}, configurable: true, enumerable: true }); person.legs = 2;
As you can see property descriptors are a lot more code, so you only use them if you really want to prevent someone from mangling your property, and also you forget about backwards compatibility with ES3 browsers because, unlike additions to Array.prototype
for example, you cannot "shim" this feature in old browsers.
And the power of the descriptors in action (defining a nonmalleable property):
> var person = {}; > Object.defineProperty(person, 'heads', {value: 1});> person.heads = 0; 0 > person.heads; 1 > delete person.heads; false > person.heads; 1
The following is a list of all ES5 additions to Object
:
Property/method |
Description |
---|---|
|
While in ES3 you have to guess what is the prototype of a given object using the method > Object.getPrototypeOf([]) ===
Array.prototype;
true
|
|
Discussed in Chapter 6, Inheritance. Creates a new object, sets its prototype and defines properties of that object using property descriptors (discussed earlier). > var parent = {hi: 'Hello'};
> var o = Object.create(parent, {
prop: {
value: 1
}
});
> o.hi;
"Hello"
It even lets you create a completely blank object, something you cannot do in ES3. > var o = Object.create(null);
> typeof o.toString;
"undefined"
|
|
Allows you to inspect how a property was defined. You can even peek into the built-ins and see all these previously hidden attributes. > Object.getOwnPropertyDescriptor(Object.prototype, 'toString'); Object configurable: true enumerable: false value: function toString() { [native code] } writable: true |
|
Returns an array of all own property names (as strings), enumerable or not. Use > Object.getOwnPropertyNames(Object.prototype);
["constructor", "toString", "toLocaleString", "valueOf",...
|
|
Defines a property of an object using a property descriptor. See the discussion preceding this table. |
|
The same as > var glass = Object.defineProperties({}, {
"color": {
value: "transparent",
writable: true
},
"fullness": {
value: "half",
writable: false
}
});
> glass.fullness;
"half"
|
|
> var deadline = {}; > Object.isExtensible(deadline); true > deadline.date = "yesterday"; "yesterday" > Object.preventExtensions(deadline); > Object.isExtensible(deadline); false > deadline.date = "today"; "today" > deadline.date; "today" Attempting to add properties to a non-extensible object is not an error, but simply doesn't work: > deadline.report = true;
> deadline.report;
undefined
|
|
This means you can change the value of an existing property, but you cannot delete it or reconfigure it (using |
|
Everything that > var deadline = Object.freeze( {date: "yesterday"}); > deadline.date = "tomorrow"; > deadline.excuse = "lame"; > deadline.date; "yesterday" > deadline.excuse; undefined > Object.isSealed(deadline); true |
|
An alternative to a > Object.prototype.customProto = 101; > Object.getOwnPropertyNames( Object.prototype); ["constructor", "toString", ..., "customProto"] > Object.keys(Object.prototype); ["customProto"] > var o = {own: 202}; > o.customProto; 101 > Object.keys(o); ["own"] |