简体   繁体   中英

Uncaught TypeError: Object function has no method

I'm sure this is very readily solved. I'm trying to invoke slowbie.tick();

Here's the code:

 function slowbie(){ //Enemy that slowly moves towards you.
    this.max = 7;
    this.w = 25;
    this.h = 25;
    this.speed = 5;
    this.points = 1;
    this.enemies = [];
    function spawn(){
        if(this.enemies < this.max){
            for (var i = this.enemies.length; i < this.max; i++) {
            this.x = width + Math.floor(Math.random()*20) + this.w;
            this.y = Math.floor(Math.random()*(height-this.h));
            this.speed = Math.floor(Math.random()*(speed-1))+1;
            this.enemies.push(
                [this.x, this.y, this.w, this.h, this.speed]);
            }
        }
    }

    function move(){
        for (var i = 0; i < this.enemies.length; i++) {
            if (this.enemies[i][0] > -this.w) {
            this.enemies[i][0] -= this.enemies[i][4];
        } else{
            this.enemies[i][0] = width;
            this.enemies[i][1] = Math.floor(Math.random()*(height-this.h));
            this.enemies[i][4] = Math.floor(Math.random()*(this.speed-1))+1;
            }
        }
    }

    function hit(){
        var remove = false;
        for (var i = 0; i < lasers.length; i++) {
            for (var j = 0; j < this.enemies.length; j++){
                if (lasers[i][0] <= (this.enemies[j][0] + this.enemies[j][2]) &&
                    lasers[i][0] >= this.enemies[j][0] &&
                    lasers[i][1] >= this.enemies[j][1] &&
                    lasers[i][1] <= (this.enemies[j][1] + this.enemies[j][3])) {
                remove = true;
                this.enemies.splice(j, 1);
                score += this.points;
                spawn();
            }
            }
            if (remove) {
            lasers.splice(i, 1);
            remove = false;
            }
        }
    }

    function draw(){
        for (var i = 0; i < this.enemies.length; i++) {
            ctx.fillStyle = '#f00';
            ctx.fillRect(this.enemies[i][0], this.enemies[i][1], this.w, this.h);
            }
        }

    this.tick = function(){
        spawn();
        hit();
        draw();
        move();
        };
}

I don't understand why tick apparently isn't a privileged method... Please assist!

You're explicitly exposing the "tick" function on the context object ( this ). If you do something like:

var s = new slowbie();
s.tick();

then that works because your code explicitly arranged for it to work.

In JavaScript, functions are functions. If you can get a reference to a function, you can always call it, no matter how it was defined. There's no such thing as "privileged" or "private" functions, at least not as far as the functions themselves are concerned. The real issue is visibiity . If a function is declared locally inside another function, and nothing in the outer function ever exposes a reference to the inner function, then nothing outside the outer function can get at the inner function. The inner function doesn't really "know" that, however, and if a reference does leak out then it can be called freely.

Now, that's the answer to the question at the end of your post. As to the title of your post, well, it's not entirely clear what you're up to. If you try this:

slowbie.tick();

well that won't work because the name "slowbie" refers to the function, and that function object has no property called "tick". To get at "tick", you have to instantiate an object with the "slowbie" function as a constructor:

var s = new slowbie();

or else explicitly use "call" or something:

var s = slowbie.call(someObject);
someObject.tick();

Finally note that if you really want to be able to call "slowbie.tick()", then you could always do this:

slowbie.call(slowbie);

That will add a "tick" property to the "slowbie" object itself (that is, the Function instance that "slowbie" actually is). Thereafter, calls to "slowbie.tick()" will work.

What makes you think it isn't? How are you trying to call tick() ?

You may want to look over Crockford's page discussing this (har har) because there are a few other issues with what I think you're trying to do, but can't quite tell.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM