Строго нарушение на 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 - така е, но мисля, че го казвам правилно, функцията трябва да бъде дефинирана в строг режим. Ако просто кажете use 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