Domanda

I'm trying to learn to do object oriented programming in JavaScript and getting JSLint strict violations. I understand that I'm using this in a non-global context (or something to that effect...), but I don't know how to do it properly. Here's my code:

function piece(color, type, x, y, captured, hasMoved) {
    "use strict";
    this.color = color;
    this.type = type;
    this.x = x;
    this.y = y;
    this.captured = captured;
    this.hasMoved = hasMoved;

    this.movePiece = movePiece;
    function movePiece(x, y) {
        // if(isLegal(x, y, this.type){
            // this.x  =  x;
            // this.y  =  y;
        // }
         alert("you moved me!");
    }
}

var whitePawn1  =  piece("white", "pawn", 0, 1, false, false);
var blackBishop1  =  piece("black", "bishop", 8, 3, false, false);
È stato utile?

Soluzione

You need to use your piece function as a constructor—in other words call it with the new keyword.

As it stands now, this inside of your function is the global object. Basically, instead of creating a new object, and adding properties to it, you're clobbering the gobal object with junk.

Since you're in strict mode, this will be undefined, so your code will error out.

This is what you want:

function Piece(color, type, x, y, captured, hasMoved) {
    "use strict";
    this.color = color;
    this.type = type;
    //...

var whitePawn1  = new Piece("white", "pawn", 0, 1, false, false);
var blackBishop1  = new Piece("black", "bishop", 8, 3, false, false);

Note that I renamed piece to start with a capital letter, since contructor functions by convention are supposed to.


Also, assuming a constructor function like this is really what you want, compared to Ian's answer, you should consider moving the movePiece function out to the function's prototype, so that function doesn't have to be re-created each and every time you create a new piece. So this

this.movePiece = movePiece;
function movePiece(x, y) {
   //...
}

would become this

//this goes **outside** of your function
Piece.prototype.movePiece = function movePiece(x, y) {
       //...
}

Altri suggerimenti

I'm not sure how it would be different internally/functionally, but you could use:

function piece(color, type, x, y, captured, hasMoved) {
    "use strict";
    return {
        color: color,
        type: type,
        x: x,
        y: y,
        captured: captured,
        hasMoved: hasMoved
    };
}

var whitePawn1 = piece("white", "pawn", 0, 1, false, false);

Which doesn't require the use of this or new.

Although I guess you couldn't use the .prototype to apply a shared property/method to all instances. And the returned object initialization is extra too.

Ah thanks Adam Rackis. That did it. For reference, here's my final JSLint verified code:

function Piece(color, type, x, y, captured, hasMoved) {
    "use strict";
    this.color = color;
    this.type = type;
    this.x = x;
    this.y = y;
    this.captured = captured;
    this.hasMoved = hasMoved;
}
Piece.prototype.movePiece = function movePiece(x, y) {
    "use strict";
    /*global alert */
    alert("you moved me to " + x + ", " + y + "!");
};
var whitePawn1  =  new Piece("white", "pawn", 0, 1, false, false);
var blackBishop1  =  new Piece("black", "bishop", 8, 3, false, false);

You are missing new keyword before invoking your constructor. Code should look like this:

var whitePawn1    = new piece("white", "pawn", 0, 1, false, false);
var blackBishop1  = new piece("black", "bishop", 8, 3, false, false);

Also it is good patter to name constructor with capital letter, in your case Piece

Explanation: without new your constructors may corrupt the environment they where invoked at. The new creates the new environment and bind it to the constructor.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top