JS原型化n-ary方法

时间:2015-07-11 17:50:40

标签: javascript html5 canvas methods prototyping

问题是我有一个JS类,并希望为其原型( Whisp.prototype.draw )创建一个n-ary方法,因此它不会一遍又一遍地实例化。我的浏览器控制台告诉我的是

  

未捕获的TypeError:w.draw不是函数

我可能误解了JS中的原型设计,所以这里是代码的相关部分:

// Random generators

function randomInt(min, max)
{
    return Math.floor(Math.random() * (max - min)) + min;
}

// Whisp object + its methods

var WHISP_TURN_CAP = 10, WHISP_WANDER_CAP = 2, WHISP_SIZE = 2,
    WHISP_COUNT = 4;

var Whisp = function(position)
{
    this.rotation = [];
    this.position = position;

    for (var i = 0; i < 3; i++)
        this.rotation.push(randomInt(-WHISP_TURN_CAP, WHISP_TURN_CAP))
    this.rotation.push(1)
}

Whisp.prototype.wander = function()
{
    var angle;
    for (var i = 0; i < 3; i++)
    {
        angle = randomInt(-WHISP_WANDER_CAP, WHISP_WANDER_CAP+1);
        while (Math.abs(this.rotation[i] + angle) > WHISP_TURN_CAP)
            angle = randomInt(-WHISP_WANDER_CAP, WHISP_WANDER_CAP+1);
        this.rotation[i] += angle;
        this.position = matrixProduct(this.position, i, this.rotation[i]);
    }
};

Whisp.prototype.draw = function(center)
{
    context.setFill('#60FF55');
    context.fillOval(
            center[0]+this.position[0]-WHISP_SIZE,
            center[1]+this.position[1]-WHISP_SIZE,
            center[0]+this.position[0]+WHISP_SIZE,
            center[1]+this.position[1]+WHISP_SIZE
        );
};

// Generate actual whisps

var whisps = [];
for (var i = 0; i < WHISP_COUNT; i++)
    whisps.push(new Whisp([800,400,0,1]));

// Update function (drawing onto canvas)

var canvas = $('#backgroundCanvas')[0], context = canvas.getContext('2d');

function update()
{
    for (var w in whisps)
    {
        w.draw([800,450]);
        w.wander();
    }
    console.log('update();');
    window.setTimeout(update, 20);
}
var whisps = [];
for (var i = 0; i < WHISP_COUNT; i++)
    whisps.push(new Whisp([800,400,0,1]));

// Update function (drawing onto canvas)

var canvas = $('#backgroundCanvas')[0], context = canvas.getContext('2d');

function update()
{
    for (var w in whisps)
    {
        w.draw([800,450]);
        w.wander();
    }
    console.log('update();');
    window.setTimeout(update, 20);
}

update();

所有这些都包含在$(document).ready(function(){...})中。谢谢你的回答:)。

1 个答案:

答案 0 :(得分:1)

您应该避免对数组使用for ...in,因为它不会迭代未定义的索引,也不保证按顺序迭代数组。
请参阅:Why is using "for...in" with array iteration a bad idea?

但问题是w将项目的键存储在数组中:

for (var w in whisps)
{
    w.draw([800,450]);
    w.wander();
}

它应该在哪里:

for (var w in whisps)
{
    whisps[w].draw([800,450]);
    whisps[w].wander();
}

甚至更好:

for (var i = 0; i < whisps.length; i++) {
    whisps[i].draw([800,450]);
    whisps[i].wander();
}

通常也会更快:Javascript for..in vs for loop performance

我注意到你正在使用canvas所以不关心IE8,在这种情况下Array.prototype.forEach()是我更喜欢的另一个解决方案,因为它为迭代创建了一个新的范围:

whisps.forEach(function(w) {
    w.draw([800,450]);
    w.wander();
});