Make polyfills immutable

80 Views Asked by At

For example:

Object.defineProperty(Promise.prototype, 'onFinally', {
  get: () => {},
  writable: false,
});

or

Object.freeze(Promise.prototype);

These examples aren't work, is there a working way?

UPD Thank you all for your help, this method really works, but in my situation the problem is different. There is a problem on the Shopify store where Promise.prototype is somehow completely overwritten, although this is unlikely. All third-party Promise.prototype properties are deleted, possibly all properties except built-in ones are deleted via delete.

3

There are 3 best solutions below

0
Amir Hossein Baghernezad On BEST ANSWER

Actually the example you provided works:

Object.defineProperty(Promise.prototype, 'onFinally', {
    get: () => { console.log("Retrieved.") }
});

Promise.prototype.onFinally

Object.freeze(Promise.prototype);

Promise.prototype.onFinally

Object.defineProperty(Promise.prototype, 'onFinallySecond', {
    get: () => { console.log("Retrieved.") }
});

TypeError: Cannot define property onFinallySecond, object is not extensible

You just have to call it in the correct order.

0
Mr. Polywhirl On

You can call Object.freeze() on the String.prototype, but if you try to redefine a method, it will silently be ignored.

Note that freezing an Object's prototype is ill-advised.

function padBoth(targetLength, padString) {
  const delta = Math.floor((targetLength - this.length) / 2);
  return delta > 0
    ? this
      .padStart(this.length + delta, padString)
      .padEnd(targetLength, padString)
    : this
}

String.prototype.padBoth = padBoth;
console.log('Hello World'.padBoth(20, '-'));

// Without this line, the try-catch (below) will throw
Object.freeze(String.prototype);

// No error, but does not reassign
String.prototype.padBoth = undefined;
try {
  console.log('Hello World'.padBoth(20, '-')); // Works, if frozen
} catch (e) {
  console.log(e.message);
}

0
Alexander Nenashev On

You can "freeze" a particular polyfill with configurable: false:

Object.defineProperty(Promise.prototype, 'onFinally', {
  get: () => 'Resolved',
  configurable: false
});

Object.defineProperty(Promise.prototype, 'onFinally', {
  get: () => 'Ha-ha-ha, not resolved',
  configurable: false
});