我想创建一个扩展CanvasRenderingContext2D
的新类。这样我就可以将用户定义的属性分配给该新类的prototype
属性,而不是CanvasRenderingContext2D.attribute
。以下是我打算编写的代码:
class WL_CRC2D extends CanvasRenderingContext2D{
constructor(){
super();
}
setStyle(args){//...
}
//...
}
var ctx = new WL_CRC2D() // Uncaught TypeError: Illegal constructor
这不起作用,因为CanvasRenderingContext2D
会阻止new
运算符 - 就像下面的代码也会抛出错误一样:
var ctx = new CanvasRenderingContext2D(); // Uncaught TypeError: Illegal constructor
然后我尝试用另一种方式重写构造函数:
class WL_CRC2D{
constructor(){
let ctxTemp = Object.create(CanvasRenderingContext2D.prototype);
for (let i of Reflect.ownKeys(ctxTemp.__proto__)){
Object.defineProperty(this.__proto__, i, Object.getOwnPropertyDescriptor(ctxTemp.__proto__, i));
}
}
setStyle(args){//...
}
//...
}
var ctx = new WL_CRC2D(); // fine
console.log(ctx.arc); // function arc() { [native code] }
ctx.arc(0, 0, 10, 0, 1, true); // Uncaught TypeError: Illegal invocation
正如评论所示,以这种方式从WL_CRC2D
创建的新实例实际上无法访问WL_CRC2D.prototype
中的属性。
那么有没有办法绕过系统定义的CanvasRenderingContext2D
类?请指教。谢谢!
答案 0 :(得分:0)
我可能用丑陋的方式想出来了:
class WL_CanvasRenderingContext2D{
constructor(ctx){
this.ctx = ctx;
}
}
(() => {
var context = document.createElement('canvas').getContext('2d');
for (let i of Reflect.ownKeys(Object.getPrototypeOf(ctx))){
if (['symbol', 'constructor'].indexOf(typeof i) < 0){
var propertyDesc = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(context), i);
if (typeof context[i] != 'function'){
[propertyDesc.get, propertyDesc.set] = [function(){return this.ctx[i]}, function(val){this.ctx[i] = val;}];
}
else{
propertyDesc.value = function(...args) {this.ctx[i].apply(this.ctx, args)};
}
Object.defineProperty(WL_CanvasRenderingContext2D.prototype, i, propertyDesc);
}
}
})();
var a = new WL_CanvasRenderingContext2D(ctx);
如果上述代码存在任何缺陷,请通知我。谢谢!