Можно ли создать объект в Javascript, не объявляя каждое значение, и как?


Я хочу сделать следующее:

var Room = function(name, north, south, east, west) {
    this.name = name;
    this.north = north;
    this.south = south;
    this.west = west;
    this.east = east;
}
Где Север, Юг, Восток и Запад - это просто флаг, говорящий, есть ли там дверь.

Когда я создаю объект, я должен сделать следующее:

var bedroom = new Room('Bedroom', true, false, false, false);
Мне было интересно, есть ли способ, чтобы я мог просто сказать, какие направления имеют истинное значение, например:
var bedroom = new Room({
    name: 'Bedroom',
    north: true
});

С юг, восток и Запад становятся ложными. таким образом, если бы у меня было, скажем, 20 различных вариантов, мне нужно было бы указать только те, которые меня волнуют, а не имея длинные декларации с большим количеством ложных и " ценностей, и мне не нужно было бы помнить, в каком порядке они должны быть (Север, Юг, Восток, Запад? или север, восток, юг, запад?),

8 3

8 ответов:

Если вам действительно нужны отдельные переменные экземпляра для north, south, east и west, я бы предложил что-то вроде этого, где вы можете передать только те направления, которые вас интересуют в строке с разделителями пространства. Это делает вызывающий код намного проще, так как вам не нужно ничего передавать для направлений, которые не существуют.

var Room = function(name, directions) {
    this.name = name;
    this.north = this.south = this.west = this.east = false;
    directions = directions.split(" ");
    directions.forEach(function(item) {
        this[item] = true;
    })
}

var bedroom = new Room('Bedroom', 'north south');

Или ваш объектный подход тоже отлично работает:

var Room = function(name, directions) {
    this.name = name;
    this.north = this.south = this.west = this.east = false;
    for (var dir in directions) {
        this[dir] = directions[dir];
    }
}

var bedroom = new Room('Bedroom', {north: true, south: true});

Третий подход заключается в использовании флагов (часто используемых в C / C++). Это позволяет вам пройти произвольное количество флагов в одном значении:
var Room = function(name, directions) {
    this.name = name;
    this.directions = directions;
}

Room.prototype = {
   isNorth: function() { return this.directions & Room.north},
   isSouth: function() { return this.directions & Room.south},
   isWest: function() { return this.directions & Room.west},
   isEast: function() { return this.directions & Room.east},
};

Room.north = 1;
Room.south = 2;
Room.east = 4;
Room.west = 8;

var bedroom = new Room('Bedroom', Room.north | Room.south);

Объекты JavaScript

Добавьте значение по умолчанию с помощью оператора ||

var Room = function(name, north, south, east, west) {
    this.name = name;
    this.north = north || false;
    this.south = south || false;
    this.west = west || false;
    this.east = east || false;
}

Это скажет ему использовать east, если данные были предоставлены для него, или использовать false, если east окажется undefined.

var Room = function (options) {
    this.name = options.name;
    var cardinals = ['north', 'south', 'east', 'west'];

    // Check your directions param for each of the cardinal directions
    // that you want to allow
    cardinals.forEach(function (direction) {
        if (typeof options[direction] !== 'undefined') {
            this[direction] = options[direction];
        } else {
            this[direction] = false;
        }
    });
};

var room = new Room({ name: 'Bedroom', north: true, south: true });

Вы можете использовать "для .. в..."цикл для итерации входного объекта с парами. Пример:

Room = function(options) {
    for (var key in options) {
        this[key] = options[key];
    }
}

var bedroom = new Room({
    name: 'Bedroom',
    north: true
});

Можно использовать оператор ||

Например

var Room = function(name, directions) {
    this.name = name;
    this.north = directions.north || false;
    this.south = directions.south || false;
    this.west = directions.west || false;
    this.east = directions.east || false;
}

Тогда при вызове var r = new Room("something", {north:true}); всем остальным значениям будет присвоено значение false.

Вы можете использовать какой-то подкласс.

В основной класс вы ставите все значения по умолчанию.

function AbstractRoom(name, north, south, east, west){
    this.name = name;
    this.north = north;
    this.south= south;
    this.east= east;
    this.west= west;
}

В свой подкласс вы помещаете свои значения

function RoomNorth(name){
  AbstractRoom.call(this, name, true, false, false, false);
}

В данном случае

var myNorthRoom = new RoomNorth('AGoodName');

Где

myNorthRoom.north <-- true
myNorthRoom.south <-- false

Как насчет:

var Room = function( name, directions ) {
    this.name = name;
    this.north = directions.north || false;
    this.south = directions.south || false;
    this.west = directions.west || false;
    this.east = directions.east || false;
}

И затем вызов конструктора типа:

var bedroom = new Room( 'Bedroom', { 'north': true } );

Если вы не зададите направление, оператор || сделает его ложным.

Вот еще один способ использования шаблона" цепочка " (это не конструктор per-se):

function Room (name) {
   this.name = name;
}

Room.prototype = {
   north: function (v) {
       if (arguments.length > 0 } { this._north = v; return this; }
       else { return this._north; }
   },
   south: function (v) {
       if (arguments.length > 0 } { this._south = v; return this; }
       else { return this._south; }
   },
   // .. rest of getter-setters
   // The prototype can be used for defaults and/or lifting
   _north: false,
   _south: false,
   // .. rest of defaults
}

var room = new Room("bedroom")
  .north(true)
  .south(true); // => the Room object

var hasNorth = room.north(); // => true

Некоторым людям может не понравиться этот шаблон - и особенно эта реализация-потому что он изменяет тип возврата геттера/сеттера, чтобы быть "иногда-цепным" и "иногда-возвращать-значение", как некоторые методы jQuery (например. $.val).

Он также требует / поощряет, чтобы направления (напр. "север") можно получить с помощью методов геттера. Определение свойств не допускает такой цепочки синтаксис.