# property

[JS](/web/js.md) ⟩ [value](/web/js/val.md) ⟩ [object](/web/js/val/obj.md) ⟩ property&#x20;

{% hint style="success" %}
a <mark style="color:purple;">**property**</mark> has a [**name**](/web/js/val/obj/prop/name.md), a [**value**](/web/js/val.md), and 3 [**attributes**](/web/js/val/obj/prop/attr.md).

* there are <mark style="color:yellow;">**two types**</mark> of properties：
  * (<mark style="color:yellow;">**data**</mark> property) stores a [value](/web/js/val.md) that is <mark style="color:red;">**not**</mark> a [**function**](/web/js/val/func.md).
  * (<mark style="color:yellow;">**function**</mark> property) stores a [**function**](/web/js/val/func.md) ([method](/web/js/val/obj/method.md)/[getter/setter](/web/js/val/obj/prop/getter-setter.md)/[Broken mention](broken://pages/GIwbj5eHtxiaIwTbZZ5T)).

```javascript
// defining/creating properties
{ name: value }    // object literal
obj.prop = value    // create property 'on the fly'

// accessing properties
obj . prop    // `prop` must be an identifier
obj [ prop ]  // `prop` convereted to String or it's a Symbol.
```

{% endhint %}

{% tabs %}
{% tab title="🔴" %}

* <mark style="color:yellow;">**accessing properties**</mark>
  * [property access expression](/web/js/val/obj/prop/access/property-access-expression.md)
    * [dot notation (.)](/web/js/val/obj/prop/access/dot-notation-..md)
    * [bracket notation \[\]](/web/js/val/obj/prop/access/bracket-notation.md)
    * [optional chaining (?., ?.\[\])](/web/js/val/obj/prop/access/optional-chaining.md) - safely access object's properties.
  * [delete](/web/js/val/obj/prop/create/delete.md) properties
  * [property testing](/web/js/val/obj/prop/test.md)
  * [property enumeration](/web/js/val/obj/prop/enumerate.md)
* <mark style="color:yellow;">**creating properties**</mark>
  * [method](/web/js/val/obj/method.md)
  * [getter/setter](/web/js/val/obj/prop/getter-setter.md) / [Broken mention](broken://pages/GIwbj5eHtxiaIwTbZZ5T)
  * [shorthand property](/web/js/val/obj/prop/shorthand.md)
  * [computed property name](/web/js/val/obj/prop/name/computed.md)
  * [private property by closure](/web/js/val/func/closure/private-prop.md)
  * [private member](/web/js/val/class/member/private.md)
  * [global object property](/web/js/scope/global/object/prop.md)
* <mark style="color:yellow;">**features of a property**</mark>
  * [attribute](/web/js/val/obj/prop/attr.md) - writable, enumerable, configurable.
  * [property name](/web/js/val/obj/prop/name.md)
    {% endtab %}

{% tab title="⭐️" %}
{% hint style="success" %}
Every <mark style="color:purple;">**property**</mark> in JavaScript [**objects**](/web/js/val/obj.md) can be <mark style="color:yellow;">**classified by**</mark>**&#x20;**<mark style="color:orange;">**3**</mark>**&#x20;**<mark style="color:yellow;">**factors**</mark>:

* [**String**](/web/js/val/prim/str.md) <mark style="color:yellow;">**/**</mark> [**Symbol**](/web/js/val/prim/symbol.md)
* <mark style="color:orange;">**enumerable**</mark>**&#x20;**<mark style="color:yellow;">**/**</mark>**&#x20;**<mark style="color:orange;">**non-enumerable**</mark>
* <mark style="color:orange;">**own**</mark>**&#x20;**<mark style="color:yellow;">**/**</mark>**&#x20;**<mark style="color:orange;">**inherited**</mark> (from the [**prototype chain**](/web/js/val/obj/proto/chain.md))

:point\_right: [property testing](/web/js/val/obj/prop/test.md) (📘 [MSN ](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Enumerability_and_ownership_of_properties))&#x20;
{% endhint %}

{% hint style="info" %}
the [**assignment**](/web/js/grammar/op/assign/assignment.md) of a <mark style="color:purple;">**property**</mark> <mark style="color:red;">**always**</mark> <mark style="color:yellow;">**creates**</mark>**/**<mark style="color:yellow;">**sets a property**</mark> in the <mark style="color:orange;">**original**</mark>**&#x20;**<mark style="color:yellow;">**object**</mark>, it <mark style="color:red;">**never**</mark> <mark style="color:yellow;">**modifies objects**</mark> in the [**prototype chain**](/web/js/val/obj/proto/chain.md).
{% endhint %}

{% hint style="info" %}
A "[variable](/web/js/variable.md)" is just a <mark style="color:purple;">**property**</mark> of the [environment record](/web/js/concept/execution-context/lexical-environment/environment-record.md) (associated with the <mark style="color:yellow;">**currently executing**</mark> [block](/web/js/grammar/statement/other/block.md) /[function](/web/js/val/func.md) /[module](/web/js/module.md) /<mark style="color:yellow;">**script**</mark>).&#x20;
{% endhint %}
{% endtab %}

{% tab title="👥" %}

* <mark style="color:yellow;">**in the**</mark> [global scope](/web/js/scope/global.md),&#x20;
  * [var](/web/js/variable/declare/var.md) / [function](/web/js/val/func.md) are <mark style="color:yellow;">**implemented**</mark> as <mark style="color:purple;">**propery**</mark> on the [global object](/web/js/scope/global/object.md).
  * these <mark style="color:purple;">**properies**</mark> can't be [delete](/web/js/val/obj/prop/create/delete.md)d:exclamation:
  * <mark style="color:yellow;">**global**</mark> [let](/web/js/variable/declare/let.md) / [const](/web/js/variable/declare/const.md) are <mark style="color:red;">**not**</mark> <mark style="color:purple;">**properies**</mark> of the [global object](/web/js/scope/global/object.md):exclamation:
* [closure](/web/js/val/func/closure.md) can be used as a [function](/web/js/val/func.md) with <mark style="color:red;">**private**</mark> <mark style="color:purple;">**propery**</mark> (functions/variables):exclamation:(:point\_right: [closure: manage grades](/web/js/val/func/closure/examples/grades.md))
* object's <mark style="color:red;">**configurable**</mark> <mark style="color:purple;">**properies**</mark> can be [delete](/web/js/val/obj/prop/create/delete.md)d:exclamation:
* [null](/web/js/val/prim/null.md) and [undefined](/web/js/val/prim/undefined.md) are the <mark style="color:red;">**only**</mark>**&#x20;**<mark style="color:yellow;">**two**</mark> [value](/web/js/val.md)s that <mark style="color:red;">**do not**</mark>**&#x20;**<mark style="color:yellow;">**have**</mark>**&#x20;**<mark style="color:purple;">**properties**</mark>.:exclamation:
  {% endtab %}

{% tab title="💈" %}

* replit：[object properties](https://replit.com/@pegasusroe/object-properties#index.js)

```javascript
// ⭐ types of properties of an object
const obj = {
    
    // ⭐ data property
    prop: 123,                                  // data property
    
    // ⭐ method/generator
    method(parameters) { },                     // method
    *generator() { },                           // generator
    
    // ⭐ getter/setter
    get getter() { return this.prop },          // getter
    set setter(value) { this.prop = value },    // setter
    
    // ⭐ getter/setter can have the same identifier❗
    get name() { return this._name },
    set name(value) { this._name = value },

    // ⭐ computed property name
    [`foo${++i}`]: i,
    [`foo${++i}`]: i,
};

// ⭐ setter called
obj.setter = 'changed';    // looks like an assignment,
                           // but `obj.setter('changed')` is called❗

// ⭐ getter called
obj.getter;    // looks like a normal property reference, but
               // it calls `obj.getter()` and returns a value ('changed').

// ⭐ getter/setter calls
//   looks like a normal property assignment/reference, but actually
//   getter/setter are called behind the scene❗
obj.name = 'joe';    // calls setter: obj.name('joe')
obj.name;            // calls getter: obj.name()

// computed property name
obj.foo1,    // 1
obj.foo2,    // 2
```

{% endtab %}

{% tab title="📗" %}

* [ ] [YDKJS: Scope & Closures (v.2)](/web/master/ref/book/you-dont-know-js-series-v.2/ydkjs-scope-and-closures-v.2.md) > Ch. 3: [The Scope Chain](https://github.com/getify/You-Dont-Know-JS/blob/2nd-ed/scope-closures/ch3.md#chapter-3-the-scope-chain)
  {% endtab %}

{% tab title="📘" %}

* [ ] [Property](https://developer.mozilla.org/en-US/docs/Glossary/property)
* [ ] [Expressions and operators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators) ⟩ [Object initializer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer) ⟩ [Method definitions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer#method_definitions)
* [ ] [Functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions) - method/getter/setter are all [function](/web/js/val/func.md)s.
  {% endtab %}
  {% endtabs %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://lochiwei.gitbook.io/web/js/val/obj/prop.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
