我是一位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'方法..但是爲什麼?在任何時候如何正確引用形狀? –