Можно ли создать объект в 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 ответов:
Если вам действительно нужны отдельные переменные экземпляра для
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
).Он также требует / поощряет, чтобы направления (напр. "север") можно получить с помощью методов геттера. Определение свойств не допускает такой цепочки синтаксис.