您可以在 Javascript 中创建对象而不声明每个值吗?如何?

Can you create an object in Javascript without declaring every value, and how?

我想执行以下操作:

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 个不同的选项,我只需要指定我关心的选项,而不是有很多错误和''值的长声明,我不需要记住它们应该处于哪个顺序(北,南,东,西?或北,东,南,西?),

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

如果你真的需要 northsoutheastwest 的单独实例变量,我建议你可以只传递您在 space 分隔字符串中关心的方向。这使得调用代码更加简单,因为您不必为不存在的方向传递任何内容。

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 或在 east 结果为 undefined 时使用 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 r = new Room("something", {north:true}); 时,所有其他值都将设置为 false。

您可以使用某种子class。

在 main class 中输入所有默认值。

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

在你的子class你把你的价值观

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

如果不定义方向 ||运算符将使它为假。

您可以使用 "for .. in ..." 循环来迭代带参数的输入对象。示例:

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

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

这是使用 "chaining" 模式的另一种方式(它本身不是构建器):

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

有些人可能不喜欢这种模式——尤其是这种实现——因为它将 getter/setter 的 return 类型更改为 "sometimes-chainable" 和 "sometimes-return-the-value",例如一些 jQuery 方法(例如 $.val)。

它还要求/鼓励通过 getter 方法访问方向(例如 "north")。定义属性不允许这样的链接语法。