getOwnPropertyDescriptor переопределенного toString должен быть неопределенным - PullRequest
0 голосов
/ 31 марта 2020

Я переопределил toString из HTMLCanvasElement.prototype.toDataURL. Когда я получаю дескриптор свойства toString, он должен вернуть undefined, но он возвращает функцию. Любые идеи, как это исправить?

Вы можете выполнить код здесь https://jsfiddle.net/nqk50a8r/

Object.defineProperty(HTMLCanvasElement.prototype.toDataURL, 'toString', {
    value: function () { return 'function toDataURL() { [native code] }';}
});

var desc = Object.getOwnPropertyDescriptor(HTMLCanvasElement.prototype.toDataURL, 'toString');

console.log(desc === undefined);

Если вы удалили блок defineProperty, вы увидите, что он возвращает undefined.

Я переопределил toDataURL следующим кодом:

Object.defineProperty(HTMLCanvasElement.prototype, 'toDataURL', {
    value: function () { return 'new valu' }
});

Если я не переопределил toString, он вернет сам код при вызове toString.

1 Ответ

1 голос
/ 31 марта 2020

HTMLCanvasElement.prototype.toDataURL не имеет собственного свойства toString по умолчанию. Метод toString, который вы получаете, ссылаясь на HTMLCanvasElement.prototype.toDataURL.toString, наследуется прототипом от Function.prototype.toString:

console.log(
  HTMLCanvasElement.prototype.toDataURL.toString === Function.prototype.toString
);

Никаких свойств не существует непосредственно в HTMLCanvasElement.prototype.toDataURL.toString. Но если вы добавите его самостоятельно, через

Object.defineProperty(HTMLCanvasElement.prototype.toDataURL, 'toString',

, тогда будет иметь такое собственное свойство, а также зарегистрирует дескриптор свойства, если вы изучите его.

Если вы хотите обезопасить свой пользовательский метод toString, оставив HTMLCanvasElement.prototype.toDataURL.toString пустым, вы можете перезаписать Function.prototype.toString.

Обратите внимание, что, хотя это технически возможно, это тоже очень странно, и это плохая идея. мутировать встроенные прототипы:

const origToString = Function.prototype.toString;
Function.prototype.toString = function() {
  if (this === HTMLCanvasElement.prototype.toDataURL) return 'function toDataURL() { [native code] }';
  else return origToString.call(this);
}
...