2010-11-10 58 views
2

我想添加功能(新方法)到内置对象(在我的情况下,类型CanvasRenderingContext2D)。Object.create和内置对象

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

我想使用的Object.create(从ES5)来扩展对象,像Object.create(context, <my_method_descriptors>),但它acessing属性时/调用扩展对象的方法无法在某些浏览器。例如,这个片段

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测试版和Safari 5,但成功的火狐4测试版和Chrome 7

又如:Object.create(new Date()).getDate()无法在所有浏览器。

有什么想法?

回答

3

CanvasRenderingContext2D对象是主机对象,这意味着一个对象,这不是JavaScript语言的一部分,而是由环境提供的对象。有特殊规则主机对象:它们基本上可以做任何他们喜欢的事情,并且没有义务像本地JavaScript对象那样行事。大多数浏览器使得它们的主对象的行为与本地对象类似; IE通常不会(参见this recent question对于示例片的IE主机对象quirkiness)

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

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

+0

不错的答案,我没有意识到本地对象的限制。我将创建一个包装。 – 2010-11-11 14:16:44

0

也许使用对象聚合可能对此有所帮助。创建另一个类,该类包含要扩展的类的对象,将新方法添加到该类中,然后...将出现悲伤部分,将所有方法调用映射到内部对象。

如果只有this是一个标准:(

+0

是的,一个全面的方法会使写包装更容易。 – 2010-11-12 00:11:58