我是一位Ruby开发人员,他最终决定认真学习JavaScript。所以我购买了一些书,然后开始潜入,但当我试图了解原型继承时,我很快就陷入了困境......JavaScript原型继承和HTML画布
本书的一个例子如下。 给定一个Shape,其中有一个绘制方法的原型,以及两个子形状:一个三角形和一个原型从Shape继承的Rectangle;
- 当我调用Triangle和Rectangle实例的绘图函数时,该方法将正确绘制它们。
- 当我添加第二种方法来显示他们的名字时,每个实例都会正确记录它。
一切都完全可以理解,直到我添加了第三种方法来填补形状......只有最后一个得到填补。不管我打给谁。为什么?画布上有什么特别的东西吗?
这里是运动的代码:
function Point(x, y) {
this.x = x;
this.y = y;
}
function Shape() {
this.points = [];
this.init();
}
Shape.prototype = {
constructor: Shape,
init: function() {
if (this.context === undefined) {
Shape.prototype.context = document.getElementById('canvas').getContext('2d');
};
if (this.name === undefined) {
Shape.prototype.name = 'generic shape'
}
},
draw: function() {
var i, ctx = this.context;
ctx.strokeStyle = 'rgb(0,0,255)';
ctx.beginPath();
ctx.moveTo(this.points[0].x, this.points[0].y);
for (i = 1; i < this.points.length; i++) {
ctx.lineTo(this.points[i].x, this.points[i].y);
}
ctx.closePath();
ctx.stroke();
},
fill: function(color) {
var ctx = this.context;
ctx.fillStyle = color;
ctx.fill();
},
say_name: function() {
console.log('Hello my name is ' + this.name)
}
};
function Triangle(a, b, c) {
this.points = [a, b, c];
this.name = 'Triangle'
this.context = document.getElementById('canvas').getContext('2d');
}
function Rectangle(side_a, side_b) {
var p = new Point(200, 200);
this.points = [
p,
new Point(p.x + side_a, p.y), // top right
new Point(p.x + side_a, p.y + side_b), // bottom right
new Point(p.x, p.y + side_b) // bottom left
];
this.name = 'Rectangle'
this.context = document.getElementById('canvas').getContext('2d');
}
(function() {
var s = new Shape();
Triangle.prototype = s;
Rectangle.prototype = s;
})();
function testTriangle() {
var p1 = new Point(100, 100);
var p2 = new Point(300, 100);
var p3 = new Point(200, 0);
return new Triangle(p1, p2, p3);
}
function testRectangle() {
return new Rectangle(100, 100);
}
function make_me_crazy() {
var t = testTriangle();
var r = testRectangle();
t.draw();
r.draw();
t.say_name();
r.say_name();
t.fill('red');
}
make_me_crazy();
<canvas height='600' width='800' id='canvas' />
谢谢!
更多细节:
- 为什么功能
say_name
工作正是我希望他说:“我是一个三角形”或“我是一个矩形”,从不“我是一个普通的形状”,但fill
函数填充矩形,尽管我在三角形实例上调用它?当人们正确回答翻转两个绘制函数调用时,我会更好地指定以下内容。问题不在于形状的颜色,而在于上下文指针。为什么只有最后一个形状被填满?如果在调用fill
之前添加更多形状,则只有最后一个填充。这意味着我在画布上做错了事。我认为这是“我绘制形状的地方”,但它似乎更像“最后一个活动形状” - 如何修复该代码以使其正常工作填充想要的形状只要我想要?我的意思是。如果我想要一个接收特定形状的实例并填充它的函数呢?
- 有没有办法访问包含在画布中的绘图?
在你的'make_me_crazy'功能,切换您的绘制调用(第一绘制矩形,然后三角形)。结果应该告诉你一些关于上下文的东西! – chazsolo
是的,你是对的。我认为背景是“我正在研究的形状”,但不是......是帆布? 如果我添加第三个形状,fill方法填充它。所以我推断上下文是最后一个活动形状,无论哪个人调用'fill'方法..但是为什么?在任何时候如何正确引用形状? –