Skip to content
Search

JavaScript:Object

lastmod 2022-04-13created 2020-10-195 edits

Object prorotype

In JavaScript, all objects are descendants of Object. Every object inherits methods and properties from Object.prototype, though they can later be overridden (Overriding).

Object.prototype.toString()
Returns a string representation of the object.

defineProperty

The Object.defineProperty() static method defines a new property directly on an object, or modifies an existing property, and then returns the object.

Key/Values/Entries

  • Object.keys, values, entries
  • Object.keys(obj) – returns an array of keys.
  • Object.values(obj) – returns an array of values.
  • Object.entries(obj) – returns an array of [key, value] pairs.

Troubleshooting

Object prototype mismatch

Given a class like the following,

class CustomError extends Error { 
    constructor(message: string) {
      super(`Lorem "${message}" ipsum dolor.`);
      this.name = 'CustomError';
    }
}
throw new CustomError('foo'); 

the expected output is Uncaught CustomError: Lorem "foo" ipsum dolor., but the actual output is Uncaught Error: Lorem "foo" ipsum dolor..

In this case, check whether target is set to es5 in tsconfig.json. There is a related issue in ES5. To work around it, you must manually adjust the prototype immediately after the super(...) call in the constructor.

class CustomError extends Error {
  constructor(message?: string) {
    // 'Error' breaks prototype chain here
    super(message); 

    // restore prototype chain
    const actualProto = new.target.prototype;

    if (Object.setPrototypeOf) {
      Object.setPrototypeOf(this, actualProto);
    } else {
      this.__proto__ = actualProto;
    }
  }
}
  • For runtimes that do not support Object.setPrototypeOf, adjust it to use __proto__ instead.
  • Unfortunately, this workaround does not work in Internet Explorer 10 and earlier. You can manually copy methods from the prototype onto the instance itself (i.e. FooError.prototype onto this), but the prototype chain itself cannot be fixed.
  • Every subclass of a class fixed this way must also set the prototype manually. <- (the biggest problem)

Better to keep it simple: raise the target version in tsconfig.json. I used esnext. babel will take care of compatibility anyway...

See also

Favorite site

author Zer0 sitemap