Properties of objects in JavaScript

Source: Internet
Author: User
Tags hasownproperty

Original: http://www.2ality.com/2012/10/javascript-properties.html

There are three different types of properties in javascript: named data attributes (named Data properties), named accessor properties (named Accessor properties), and internal properties (internal property).

Named Data properties

This property is the "normal" attribute that we typically use, which is used to map a string name to a value. For example, the following object, obj, has a data property named string "prop", which has a value of 123.

var obj = {
PROP:123};

You can get (read) The value of a property:

Console.log (Obj.prop); 123console.log (obj["prop"]); 123

You can also set (write) the value of a property:

Obj.prop = "ABC";
obj["prop"] = "abc";
Named Accessor properties

Alternatively, you can use a function to get or set the value of a property. These functions are called accessor functions (accessor function). Accessor functions that control property reads are called getters. Accessor functions that control property writes are called Setters.

var obj = {
Get Prop () {
return "Getter";
},
Set Prop (value) {
Console.log ("Setter:" +value);
}
}

Let's manipulate the properties of obj :

> Obj.prop
' Getter '
> Obj.prop = 123;
Setter:123
Internal properties

Some properties are only used for specifications, called internal properties, because they are not directly accessible through JavaScript, but they do exist and affect the performance of the program. The names of the internal properties are special, and they are surrounded by two brackets. Here are two examples:

    • The internal property [[[Prototype]] points to the prototype of the owning object. The value of this property can be read to by the object.getprototypeof () function . The value of this property can only be passed when a new object is created Object.create () or __proto__ to set [1].
    • The internal property [[extensible]] Determines whether a new property can be added to the owning object. The value of this property can be read through object.isextensible () . You can also Object.preventextensions () Sets the value of this property to False. Once set to false, it is no longer possible to set back to true .
Attribute Properties

All States of a property, including its data and metadata, are stored in the attribute's attributes (attributes). properties have their own attributes, just as objects have their own properties. The name of the attribute is often written in the form of a similar internal property (double brackets).

Here are the attributes owned by the named Data property:

    • [[Value]] stores the value of the property, which is the data of the property.
    • [[writable]] stores a Boolean value that indicates whether the value of the property can be changed.

The following are the attributes owned by the named accessor property:

    • [[Get]] stores the Getter, which is the function that is called when the property is read. The value returned by the function is the value of this property.
    • [[Set]] stores the setter, which is the function that is called when the property is assigned a value. The function is passed to a parameter when it is called, and the value of the parameter is the new value assigned.

Here are the characteristics of both types of properties:

    • [[[Enumerable]] stores a Boolean value. You can have a property that cannot be enumerated and hide itself under certain actions (explained in more detail below).
    • [[Configurable]] stores a Boolean value. If False, you cannot delete this property, you cannot change most of the attributes (except [[Value]]), you cannot redefine a data property as an accessor property, or vice versa. In other words: [[ Configurable]] controls the writable nature of a property's metadata.
Default value

If you do not explicitly specify a value for an attribute, they will be assigned a default value:

Attribute name Default value
[[Value]] Undefined
[[Get]] Undefined
[[Set]] Undefined
[[Writable]] False
[[Enumerable]] False
[[Configurable]] False

These default values are especially important for property descriptors.

Property descriptor

Property descriptor can encode all attributes of a property into an object and return it. Each property of the object corresponds to an attribute of the owning property. For example, the following is a property descriptor for a read-only property with a value of 123:

{
Value:123,
Writable:false,
Enumerable:true,
Configurable:false}

You can also use an accessor property to implement the above data property with a read-only attribute with the following property descriptor:

{    get:function () {return 123},    //no set, i.e. read    -only enumerable:true,    Configurable:false}
Functions that use property descriptors

The property descriptor is used when using the following function:

  • Object.defineproperty (obj, propname, PropDesc)
    Creates or alters the propname Propertyof the object obj, the attribute of thepropname property is given through the property descriptor Propdesc . Returns the modified Obj object. For example:
    var obj = Object.defineproperty ({}, "Foo", {
    Value:123,
    Enumerable:true //writable and configurable as default});
  • Object.defineproperties (obj, propdescobj)
    the batch version of Object.defineproperty () . Each property of the object Propdescobj specifies a property and corresponding property descriptor to add or modify to the original object, obj . For example:
    var obj = Object.definepropertys ({}, {
    Foo: {value:123, enumerable:true},
    Bar: {value: ' abc ', Enumerable:true}
    });
  • Object.create (Proto, Propdescobj?)
    First, create a prototype object that is proto . Then, if an optional parameter propdescobjis provided, the property is added to the new object by object.defineproperties adding the property . Finally, returns the new object after the operation. For example, the following code creates an object that is exactly the same as the object created by the Object.definepropertys example above:
    var obj = object.create (Object.prototype, {
    Foo: {value:123, enumerable:true},
    Bar: {value: ' abc ', Enumerable:true}
    });
  • Object.getownpropertydescriptor (obj, propname)
    Returns the property descriptor of the object obj named propname , which is not an inherited property. If you do not have this property, the undefinedis returned.
    > Object.getownpropertydescriptor (Object.prototype, "toString")
    {value: [function:tostring],
    Writable:true,
    Enumerable:false,
    Configurable:true}

    > Object.getownpropertydescriptor ({}, "toString")
    Undefined
Enumerable

This section explains what operations are affected by the enumerable nature of the property, and what does not. We first assume that we have defined objects such as proto and obj:

var proto = Object.defineproperties ({}, {
Foo: {value:1, enumerable:true},
Bar: {value:2, Enumerable:false}
});
var obj = Object.create (Proto, {
Baz: {value:1, enumerable:true},
Qux: {value:2, Enumerable:false}
});

It is important to note that all objects (including the protoabove) generally have at least one prototype object.prototype [2]:

> object.getprototypeof ({}) = = = Object.prototype
True

our commonly used built-in methods such as ToString and hasOwnPropertyis in fact defined on object.prototype .

Actions that are affected by enumerable

The enumerable affects only two operations: the for-in Loop and the Object.keys ().

The for-in loop iterates through the names of all the enumerable properties of an object, including inherited properties:

> for (var x in obj) console.log (x);   No enumerable property is traversed on Object.prototype Quxbazfoo

Object.keys () returns all enumerable genera of an object Sex (Non-inherited) the name of the array that consists of :

> Object.keys (obj)
[' Baz ']

If you want to get all of your own properties, you should use object.getownpropertynames ().

Actions that are not affected by enumerable

In addition to the two actions above, the enumeration of properties is ignored by other operations. Some read operations use inherited attributes:

> "toString" in obj
True> obj.tostring
[Function:tostring]

There are also some operations that only consider their own properties:

> object.getownpropertynames (obj)
[' Baz ', ' Qux ']

> Obj.hasownproperty ("Qux")
True> obj.hasownproperty ("toString")
False> object.getownpropertydescriptor (obj, "Qux")
{Value:2,
Writable:false,
Enumerable:false,
Configurable:false}
> object.getownpropertydescriptor (obj, "toString")
Undefined

Create, delete, and define properties that affect only their properties:

Obj.propname = value
obj["propname"] = value

Delete Obj.propname
Delete obj["PropName"]

Object.defineproperty (obj, propname, desc)
Object.defineproperties (obj, descobj)
Best practices

The general rule is that the properties created by the system are not enumerable and user-created properties are enumerable:

> Object.keys ([])
[]
> object.getownpropertynames ([])
[' Length ']
> Object.keys ([' A '])
[' 0 ']

Especially for the methods on the prototype object:

> Object.keys (Object.prototype)
[]
> Object.getownpropertynames (Object.prototype)
[hasOwnProperty ',
' ValueOf ',
' Constructor ',
' toLocaleString ',
' isPrototypeOf ',
' propertyIsEnumerable ',
' ToString ']

Therefore, in your own code, you should not normally add attributes to the built-in prototype object, and if you have to do so, you should set this property to be non-enumerable to prevent other code from being affected.

As we can see, the benefit of non-enumeration is that it ensures that for-in statements in existing code are not affected by attributes inherited from the prototype. However, a non-enumerable property can only create an illusion that "for-in only iterates over an object's own properties". In your code, The use of for-in[3 should still be avoided as far as possible].

If you use an object as a string-to-value map, you should only manipulate its properties and omit the enumerable. There are many other pitfalls to consider in this case [4].

Conclusion

In this paper, we study the properties of attributes (called attributes). It is important to note that the JavaScript engine does not have to be an attribute to organize a property, They are primarily an abstract operation as defined in the ECMAScript specification. But sometimes these features are also explicitly in the language code, such as in the property descriptor.

Reference
    1. JavaScript: __proto__
    2. What object is a instance of object?
    3. Iterating over arrays and objects in JavaScript
    4. The pitfalls of using objects as maps in JavaScript

Properties of objects in JavaScript

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.