Zhen Zhang


Eloquent JS: The Secret Life of Objects

June 13, 2026

1.Each abstract data type has an interface, the collection of operations that external code can perform on it.

2.You can not refer to the this of the wrapping scope in a regular function defined with the function keyword. Arrow functions are different--they do not bind their own this but can see the this binding of scope arround them. Thus you can do something like the following code which reference this from inside a local function

let finder = {
  find(array){
    return array.some(s=>s==this.value);
  }
  value: 5
};
3.Plain old object created with {} notation are linked to an object called object prototype.

4.You can use Object.create to creat a object with a specific prototype.

let blackRabbit = Object.create(protoRabbit);.

5.To created an instance of a given class, You have to make an object that derives from the proper prototype but you also have to make sure it itself has the properties that instances of this class are supposed to have. This is what a constructor function does.

6.Constructor, in JavaScript, are called by putting the keyword new in front of them. Doing so creates a fresh instance object whose prototype is the object from the function's prototype property, then run the function with this bound to the new object, and finally returns the object let killerRabbit = new Rabbit("killer");.

7.For this reason, all non-arrow functions start with a prototype.property holding an empty object.

8.It is important to understand the distinction between the way--prototype is associated with a constructor(through its prototype) and the way objects have a prototype(which can be found with object.getPrototypeOf).

9.The actual prototype of a constructor is Function.prototype since constructors are functions. The constructor functions prototype property holds the prototype used for instances created through it
console.log(Object.getPrototypeOf(Rabbit)==Function.prototype));
//true
console.log(Object.getPrototypeOf(killerRabbit) == Rabbit.prototype);
//true
10.It is also possible to declare properties directly in the class declaration. Unlike methods, such properties are added to instance objects and not the prototype
class Particle(){
  speed = 0;
  constructor(position){
    this.position = position;
  }
}
11.Like function, class can be used both in statements and in expressions, when used as an expression, it doesn't define a binding but just produces the constructor as a value. You are allowed to omit the class name in a class expression
let object = new class {
  getWord(){
    return "hello";
  }
}
//hello
12.To use private instance properties, you must declare them. Regular properties can be created by just assigning to them, but private properties must be declared in the class declaration to be available at all.

13.
console.log([1, 2]).toString());
console.log(Object.prototype.toString.call([1, 2]);
//[object Array]
14.If you pass null to Object.create, the resulting object will not derive from Object.prototype and can be safely used as a map.

15.JavaScript comes with a class called Map that is writter for this exact purpose. It stores a mapping and allows any type of keys(set, get, has).

16.Object.keys(), Object.hasOwn.

17.When a piece of code is written to work with objects that have a certain interface -- in this case, a toString method -- any kind of object that happens to support this interface can be plugged into the code and will be able to work with it. The technique is called polymorphism
Array.prototype.forEach.call({	
  length: 2,
  0: "A",
  1: "B"
  }, elt => console.log(elt));
18.Symbol are values created with the Symbol function. Unlike strings newly created symbols are unique -- You cannot create the same symbol twice
let sym = Symbol("name");
  console.log(sym == Symbol("name"));
  //false
  Rabbit.prototype[sym] = 55;
  console.log(killerRabbit[sym]);
19.Inheritance can be a useful tool to make some types of programs more succinct, but it shouldn't be the first tool reach for, and you probably shouldn't actively go looking for opportunities to constructor class hierarchies(family trees of classes).

20.The ... syntax in array notation and function call similarly works with any iterable object. For example, you can use [...value] to create an array containing the elements in an arbitraty iterable object
console.log([..."PCI"]);
//["P", "C", "I"]
21.
class LengthList extend List {
  #length;
  constructor(value, rest){
    super(value, rest);
    this.#length = super.length;
  }
  get length(){
    return this.#length;
  }
}
We can use super.something to call methods and getters on the superclass prototype, which is often useful.

22.
class List {
  constructor(value, rest) {
    this.value = value;
    this.rest = rest;
  }

  get length(){
    return 1 + (this.rest? this.rest.length:0);
  }

  static fromArray(array) {
    let result = null;
    for(let i =array.length -1;i>=0;i--){
      let result = new this(array[i], result);
    }
    return result;
  }
}

class ListIterator {
  constructor(list) {
    this.list = list;
  }

  next() {
    if(this.list.rest == null){
      return {done: true};
    }  
    let value = this.list.value;
    this.list = this.list.rest;
    return {value, done:false}
  } 
}

List.prototype[Symbol.iterator] = Function() {
  return new ListIterator(this);
}


About Privacy Home