Objects: The Basics

Objects

Symbol type

Iterables

Make any object usable in a for...of loop

funcName[Symbol.iterator] = () => {
  return {
    current: this.from,
    last: this.to

    next() {
      if (this.current <= this.last) {
        return { done: false, value: this.current++ };
      } else {
        return { done: true };
      }
    }
  }
}
let str = "Hello";

let iterator = str[Symbol.iterator]();

while (true) {
  let result = iterator.next();
  if (result.done) break;
  console.log(result.value);
}
let arrayLike = {
  0: "hello",
  1: "world",
  length: 2,
};
let arr = Array.from(arrayLike);
console.log(arr);

Object.keys, values, entries

Object.keys

Object.keys(obj);
// Return [key1, key2,...]

Object.values

Object.values(obj);
// Return [value1, value2, ...]

Object.entries

Object.entries(obj);
// Return [[key1, value1], [key2, value1], ...]

Object.fromEntries

const array = Object.entries(obj);
Object.fromEntries(array);
// Return the object from array

Transforming objects

let originalObj = Object.fromEntries(
    Object.entries(initialObj).map(entry => [entry[0], entry[1]]);
);

Destructuring assignment

Array destructuring

let arr = ["Khoa", "Tu"];
let [word1, word2] = arr; // word1 = "Khoa", word2 = "Tu"

The rest ...

let [word1, word2, ...rest] = []; // rest is a new array of the rest element

Default values

let [name = "Guest", surname = "Anonymous"] = ["Julius"];
// name="Julius" (from array)
// surname="Anonymous" (default used)

Object destructuring

let { field1, field2 } = obj;
let { field1: f1, field2: f2 } = obj;
let { value1 = val1, value2 = val2, field } = obj;
let { field1, ...rest } = obj;

Nested destructuring

let options = {
  size: {
    width: 100,
    height: 200
  },
  items: [1, 2],
  extrat: true
};

// Destructuring
let {
  size: {
    width,
    height
  },
  items: [item1, item2],
  title: "Menu" // not present in the object
} = options;

Date and time

JSON methods, toJSON

let room = {};
let meetup = {};
meetup.place = room; // meetup references room
room.occupiedBy = meetup; // roon references meetup
JSON.stringify(meetup); // Error
let json = JSON.stringify(value[, replacer, space])
function replacer(key, value) {
  console.log(`${key}: ${value}`);
  return key === "a_field_we_want_to_exclude" ? undefined : value;
}
JSON.strignify(user, null, 2); // format 2 space
JSON.parse(str, [reviver]);
JSON.parse(str, function (key, value) {
  // A date string may not be a Date object so we have to
  // update it to a Date object
  if (key == "date") return new Date(value);
  return value;
});

Object properties configuration

Property flags and descriptors

Propety flags

Object properties, besides a value, have three special attributes:

Method Object.getOwnPropertyDescriptor allows to query the full information about a property

let descriptor = Object.getOwnPropertyDescriptor(obj, propertyName);

To change the flags, we can use Object.defindProperty

Object.defineProperty(obj, propertyName, descriptor);
Object.defineProperty(user, "name", {
  value: "John",
});

Object.defineProperties help an object to define multiple properties

Object.defineProperties(obj, {
  prop1: descriptor1,
  prop2: descriptor2,
  // ...
});