JSLint Строгое нарушение. Разочарования объектно-ориентированного Javascript

Я пытаюсь научиться делать объектно-ориентированное программирование в JavaScript и получать строгие нарушения JSLint. Я понимаю, что использую это в неглобальном контексте (или что-то в этом роде...), но я не знаю, как это сделать правильно. Вот мой код:

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);

person Captain Stack    schedule 12.04.2013    source источник
comment
Что такое конкретное сообщение jslint?   -  person Aaron Kurtzhals    schedule 12.04.2013


Ответы (4)


Вам нужно использовать функцию piece в качестве конструктора — другими словами, вызывать ее с помощью ключевого слова new.

На данный момент this внутри вашей функции является глобальным объектом. По сути, вместо того, чтобы создавать новый объект и добавлять к нему свойства, вы затираете глобальный объект мусором.

Поскольку вы находитесь в строгом режиме, this будет неопределенным, поэтому ваш код выдаст ошибку.

Это то, что вы хотите:

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);

Обратите внимание, что я переименовал piece так, чтобы он начинался с заглавной буквы, так как по соглашению предполагается, что функции конструктора.


Кроме того, предполагая, что функция конструктора, подобная этой, действительно то, что вам нужно, по сравнению с ответом Яна, вам следует подумать о переносе функции movePiece в прототип функции, чтобы эту функцию не нужно было воссоздавать каждый раз, когда вы создаете новый кусок. Так это

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

станет этим

//this goes **outside** of your function
Piece.prototype.movePiece = function movePiece(x, y) {
       //...
}
person Adam Rackis    schedule 12.04.2013
comment
Я думал, что в строгом режиме this не определено, если только вы не вызываете функцию через объект. (то есть: это больше не глобальный объект по умолчанию.) - person cHao; 13.04.2013
comment
@cHao - да, но, думаю, я правильно говорю, функция должна быть определена в строгом режиме. Если вы просто скажете использовать strict внутри функции, то это все еще окно, как обычно. - person Adam Rackis; 13.04.2013
comment
О, это должно быть внутри скрипта строгого режима? - person cHao; 13.04.2013
comment
@cHao - ах, только что проверил еще раз. Я был неправ. Обновление моего ответа. - person Adam Rackis; 13.04.2013

Я не уверен, как это будет отличаться внутри/функционально, но вы можете использовать:

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);

Что не требует использования this или new.

Хотя я предполагаю, что вы не можете использовать .prototype для применения общего свойства/метода ко всем экземплярам. И инициализация возвращаемого объекта тоже дополнительная.

person Ian    schedule 12.04.2013

Ах, спасибо, Адам Рэкис. Это сделало это. Для справки, вот мой окончательный проверенный код JSLint:

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);
person Captain Stack    schedule 12.04.2013

Вам не хватает ключевого слова new перед вызовом конструктора. Код должен выглядеть так:

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

Также неплохо было бы назвать конструктор с большой буквы, в вашем случае Piece

Объяснение: без new ваши конструкторы могут повредить среду, в которой они вызываются. new создает новую среду и привязывает ее к конструктору.

person chrmod    schedule 12.04.2013