# Objects cheatsheet

[Download image version](https://github.com/cheatjs/cheat/blob/master/JavaScript/Objects/js-objects.png)

## Basic usage

Objects are used to store keyed collections of various data and more complex entities.

```js
const app = {
    name: "todo",
    version: 1.2,
};

alert(app.name); // todo
alert(app.version); // 1.2

app.version = 1.3; // update value
app.license = "MIT"; // add new property
delete app.version; // delete property
```

* **Multiword property name**

```js
const game = {
    name: "sudoku",
    "is free": true,
};

alert(game["is free"]); // true

const isFree = "is free";
alert(game[isFree]); // true
```

* **Computed property**

```js
let prop = "yEaR";
prop = prop.toLowerCase();

const list = {
    [prop]: 2022,
};

alert(list.year); // 2022
```

* **Property value shorthand**

```js
function createUser(login, id) {
    return {
        login, // the same login: login
        id, // the same id: id
    };
}
```

***

## References and copying

* **Copying objects**\
  \&#xNAN;*When copied, the new object will be a reference to the original object, unlike regular variables, which create independent entities when copied*

```js
const original = {
    name: "origin",
    id: 1,
};

const copy = original;

alert(copy.name); // origin
alert(copy.id); // 1

copy.name = "new copy"; // it also changes original

alert(original.name); // new copy
```

* **Object comparison**\
  \&#xNAN;*The comparison operators `==` and `===` work the same for objects*

```js
// Two variables refer to the same object
const original = {};
const copy = original;

alert(original == copy); // true
```

```js
// Two independent objects
const original = {};
const otherOriginal = {};

alert(original == otherOriginal); // false
```

* **Cloning objects**\
  \&#xNAN;*`Object.assign(target, ...sources)` - copies all enumerable own properties from one or more source objects to a target object.*

```js
const item = {
    name: "monitor",
    color: "black",
};

const newItem = Object.assign({}, item);

newItem.color = "gray";

alert(newItem.color); // gray
alert(item.color); // black
```

***

## Iterating objects

* Loop **for...in**

```js
const item = {
    name: "Pizza",
    price: 29,
};

for (key in item) {
    alert(`${key} - ${item[key]}`);
    // name - Pizza
    // price - 29
}
```

* **Object.keys**(object)\
  \&#xNAN;*Returns an array of keys of the passed object*

```js
console.log(Object.keys(item));
// [name, price]
```

* **Object.values**(object)\
  \&#xNAN;*Returns an array of values of the passed object*

```js
console.log(Object.values(item));
// ["Pizza", 29]
```

* **Object.entries**(object)\
  \&#xNAN;*Returns an array of the \[key, value] pairs of the passed object*

```js
console.log(Object.entries(item));
// [["name", "Pizza"], ["price", 29]]
```

***

## Object methods & this

* **Object methods**\
  \&#xNAN;*In addition to values, objects can have methods that perform various actions*

```js
const greetings = {
    hiMorning() {
        alert("Good morning!");
    },
    hiDay() {
        alert("Good afternoon!");
    },
    hiEvening() {
        alert("Good evening!");
    },
};

greetings.hiDay(); // Good afternoon!
```

* **this**\
  \&#xNAN;*`this` allows to refer to variables and methods that are stored in the same object*

```js
const counter = {
    value: 0,
    inc() {
        this.value++;
    },
    dec() {
        this.value--;
    },
};

counter.inc(); // counter.value = 1
counter.inc(); // counter.value = 2
counter.dec(); // counter.value = 1
```

*`this` is simply a reference to the object in the context of which it was called*

```js
const obj = {
    value: "hello",
    log() {
        console.log(this);
    },
};

obj.log(); // { value: 'hello', log: [Function] }
```

***

## Constructors

* **Constructor functions**\
  \&#xNAN;*Constructor functions are used to easily create objects. They are normal functions, but developers have agreed that such functions are capitalised and called with `new` operator.*

```js
function Animal(type, color) {
    this.type = type;
    this.color = color;
}

const kitten = new Animal("cat", "black");
alert(kitten.type); // cat
alert(kitten.color); // black
```

* **Methods in constructors**

```js
function Parrot(name) {
    this.name = name;
    this.greet = function () {
        alert(`Hello, my name is ${this.name}`);
    };
}

const blueParrot = new Parrot("Mojo");
blueParrot.greet(); // Hello, my name is Mojo
```

***

## Property existance

* **Checking property existence**

```js
const response = {
    data: "secret info",
    status: 200,
};

console.log("data" in response); // true
console.log("message" in response); // false
```

* **Optional chaining**\
  \&#xNAN;*Is a safe way to access nested object properties, even if an intermediate property doesn’t exist*

```js
const response = {
    data: "some data",
};

console.log(response?.data); // some data
console.log(response?.message); // undefined
```

***

## Flags & descriptors

Object properties can store a special configuration flags in addition to the value.\\

**`writable`** – if `true`, the value can be changed, otherwise it’s read-only.\
\&#xNAN;**`enumerable`** – if `true`, then listed in loops, otherwise not listed.\
\&#xNAN;**`configurable`** – if `true`, the property can be deleted and these attributes can be modified, otherwise not.

> All flags default to true

* Object.**getOwnPropertyDescriptor**(obj, property)\
  \&#xNAN;*Allows to query the full information about a property*

```js
const person = {
    name: "Bill",
    surname: "Gates",
};

let descriptor = Object.getOwnPropertyDescriptor(person, "name");

console.log(descriptor);
// {
//    configurable: true
//    enumerable: true
//    value: Bill
//    writable: true
// }
```

* Object.**defineProperty**(obj, property, descriptor)\
  \&#xNAN;*Change the flags of the specified property*

```js
Object.defineProperty(person, "name", {
    writable: false,
});
```

* Object.**defineProperties**(obj, {prop: descr, ...})\
  \&#xNAN;*Allows to define many properties at once*
* Object.**getOwnPropertyDescriptors**(obj)\
  \&#xNAN;*Get all property descriptors at once*

***

## Getters & setters

Getters and setters called as accessor properties. They are essentially functions that execute on getting and setting a value, but look like regular properties to an external code.

* **Usage**\
  \&#xNAN;*The `get` keyword is used to create the getter, for the setter - `set`*

```js
const person = {
	name: "Bill",
	surname: "Gates",
	get fullName() {
		return `${this.name} ${this.surname}`
	}
	set fullName(value) {
		[this.name, this.surname] = value.split(" ")
	}
}

alert(person.fullName) // Bill Gates

person.fullName = "Jack Ma"
console.log(person)
// {fullName: "Jack Ma", name: "Jack", surname: "Ma"}
```

* **Accessor descriptors**\
  \&#xNAN;*For accessor properties, there is no `value` or `writable`, but instead there are `get` and `set` functions*

```js
Object.defineProperty(person, "sayHello", {
    get() {
        return `Hello, I'm ${this.name}`;
    },
    enumerable: false,
    configurable: true,
});
```


---

# 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://yurace.gitbook.io/cheatjs/javascript/js-objects.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.
