2

我正在尝试将功能(新方法)添加到内置对象(在我的例子中,类型为 CanvasRenderingContext2D)。

第一种方法是将方法添加到原型中,它可以工作,但我不想修改内置对象。

我正在考虑使用 Object.create(来自 ES5)来扩展对象,例如Object.create(context, <my_method_descriptors>),但是在访问扩展对象的属性/调用方法时,它在某些浏览器上失败。例如,这个片段

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

在 IE9 Beta 和 Safari 5 上会失败,但在 Firefox 4 Beta 和 Chrome 7 上会成功。

另一个例子:Object.create(new Date()).getDate()在所有浏览器中都失败。

有什么想法吗?

4

2 回答 2

3

CanvasRenderingContext2D对象是一个宿主对象,意思是一个不属于 JavaScript 语言的对象,而是一个由环境提供的对象。宿主对象有一些特殊的规则:它们基本上可以做任何他们喜欢的事情,并且没有义务以任何方式像原生 JavaScript 对象那样行事。大多数浏览器使它们的宿主对象的行为与本机对象大体相似。IE 通常不会(有关 IE 主机对象怪癖的示例,请参阅这个最近的问题)。

这样做的结果是你永远不应该依赖宿主对象来表现得像本机对象。他们没有义务也经常没有,就像在这种情况下一样。我建议创建一个包装器对象。

Object.create(new Date()).getDate()情况不同:问题在于方法的实现依赖getDate()于它所调用对象的内部时间属性,它无法访问该属性,因为该特定属性不是沿原型链继承的。有关更详细的说明,请参阅此讨论。

于 2010-11-10T23:13:24.587 回答
0

也许在这里使用对象聚合可能会有所帮助。创建另一个包含您要扩展的类的对象的类,向其中添加新方法,然后......这是可悲的部分,将所有方法调用映射到内部对象。

如果只是一个标准:(

于 2010-11-10T22:41:54.350 回答