Object.create и встроенные объекты - PullRequest
2 голосов
/ 11 ноября 2010

Я пытаюсь добавить функциональность (новые методы) во встроенный объект (в моем случае, типа CanvasRenderingContext2D).

Первый подход состоял в том, чтобы добавить методы к прототипу, он работает, но я бы предпочел не изменять встроенные объекты.

Я думал использовать Object.create (из ES5) для расширения объекта, что-то вроде Object.create(context, <my_method_descriptors>), однако в некоторых браузерах происходит сбой при доступе к свойствам / вызову методов для расширенного объекта.Например, этот фрагмент

var canvas = document.getElementById("mainCanvas");<br> var context = canvas.getContext('2d');<br> var exContext = Object.create(context);<br> try {<br> exContext.fillStyle = 'red';<br> exContext.fillRect(0, 0, 120, 120);<br> } catch (e) {<br> alert(e);<br> }

завершится с ошибкой в ​​IE9 Beta и Safari 5, но завершится успешно в Firefox 4 Beta и Chrome 7.

Другой пример: Object.create(new Date()).getDate() не работает во всех браузерах.

Есть мысли?

Ответы [ 2 ]

3 голосов
/ 11 ноября 2010

Объект CanvasRenderingContext2D - это хост-объект , означающий объект, который не является частью языка JavaScript, а является объектом, предоставленным средой.Существуют специальные правила для хост-объектов: они могут по существу делать все, что угодно, и не обязаны вести себя как-либо как нативные объекты JavaScript.Большинство браузеров заставляют свои хост-объекты вести себя в основном так же, как и нативные объекты;Как правило, IE этого не делает (см. этот недавний вопрос для примера необычной причуды хост-объекта IE).

Следствием этого является то, что вам никогда не следует полагаться на хост-объекты, ведущие себя какродные предметы.Они не обязаны и часто не делают, как в этом случае.Я бы посоветовал создать объект-оболочку.

Случай Object.create(new Date()).getDate() отличается: проблема в том, что реализация метода getDate() зависит от внутреннего свойства time вызываемого объекта, чтоон не может получить доступ, потому что это конкретное свойство не наследуется по цепочке прототипов.См. это обсуждение для более подробного объяснения.

0 голосов
/ 11 ноября 2010

Может быть, использование агрегации объектов может помочь здесь. Создайте другой класс, который содержит объект класса, который вы хотите расширить, добавьте в него новые методы и ... вот вам грустная часть, отобразите все вызовы методов на внутренний объект.

Если бы только , этот был стандартом: (

...