如何有条件地向javascript对象文字添加属性

时间:2014-02-05 04:39:29

标签: javascript object

我正在尝试执行以下操作以满足代码构建器的要求(Sencha Cmd具体)。

这就是我需要做的事情。关键因素是函数体必须以对象文字的返回结束。由于构建器的限制,我无法返回变量。因此,如果参数'includeB'为true,如何在伪代码点处添加属性'b',但如果为false,则不添加属性AT ALL。即b == undefined或b == null是不允许的。

也许这是不可能的。

function create(includeB) {
        // Can have code here but the final thing MUST be a return of the literal.
        // ...
    return {
        a : 1
        // pseudo code:
        // if (includeB==true) then create a property called b 
        // and assign a value of 2 to it. 
        // Must be done right here within this object literal
    }
}

var obj = create(false);
// obj must have property 'a' ONLY

var obj = create(true);
// obj must have properties 'a' and 'b'

感谢阅读和考虑,

默里

9 个答案:

答案 0 :(得分:9)

如果您可以使用ES6,请使用spread properties

function create(includeB) {
    return {
        a : 1,
        ...(includeB ? { b: 2 } : {}),
    };
}

答案 1 :(得分:3)

您已经显示了构造函数的用例,而不是使用对象文字:

function CustomObject(includeB) {
    this.a = 1;
    if (includeB) {
        this.b = 2;
    }
}

//has `a` only
var obj1 = new CustomObject(false);

//has `a` and `b`
var obj2 = new CustomObject(true);

重新阅读您的问题后,您似乎在修改功能时获得了有限的访问权限。如果我正确理解您的问题,您只能更改脚本的有限部分:

function create(includeB) {
    // modifications may be done here

    // the rest may not change
    return {
        a : 1
    }
}

var obj = create(false);
// obj must have property 'a' ONLY

var obj = create(true);
// obj must have properties 'a' and 'b'

如果是这种情况,那么你可以简单地跳过函数的后面部分:

function create(includeB) {
    if (includeB) {
        return {
            a: 1,
            b: 2
        };
    }
    return {
        a: 1
    };
}

答案 2 :(得分:1)

您不能将布尔逻辑放在javascript文字定义中。因此,如果您的构建器要求返回的对象只能被定义为javascript文字,那么您无法以这种方式有条件地定义属性。


如果你可以在你的函数中创建一个对象,使用逻辑修改该对象,然后返回该对象,那就非常容易。

function create(includeB) {
    var x = {
        a: 1
    };
    if (includeB) {
        x.b = 2;
    }
    return x;
}

您的另一个选择是包装create函数并在create function之外执行。

function myCreate(includeB) {
    var x = create(includeB)
    if (includeB) {
        x.b = 2;
    }
    return x;
}

或者,您甚至可以透明地包装create函数,以便调用者仍然使用create(),但它的行为已被更改。

var oldCreate = create;
create = function(includeB) {
    var x = oldCreate(includeB);
    if (includeB) {
        x.b = 2;
    }
    return x;
}

答案 3 :(得分:1)

这应该完全符合您的要求:

const obj = {
    a: 1,
    b: includeB ? 2 : undefined
}

答案 4 :(得分:1)

我最近不得不这样做,并发现你可以在对象的定义中使用自调用函数(如果使用ES6)。这与已接受的答案类似,但对于需要在未先定义构造函数的情况下执行此操作的其他人可能会有用。

例如:

let obj = (() => {
  let props = { a: 1 };
  if ( 1 ) props.b = 2;
  return props;
})();

制作对象:{a:1,b:2}

对于更复杂的物体,它可以很方便地保持结构的连续性:

let obj = {
  a: 1,
  b: (() => {
    let props = { b1: 1 };
    if ( 1 ) props.b2 = 2;
    return props;
    })(),
  c: 3
}

制作对象:

{
  a: 1,
  b: {
    b1: 1,
    b2: 2
  },
  c: 3
}

答案 5 :(得分:0)

您可以稍后再定义:

var hasA = create(); // has hasA.a

var hasBoth = create();
hasBoth.b = 2; //now has both

或者,使用create中的参数:

function create (includeB) {
  var obj = { 
    a : 1
  };
  if (includeB) {
     obj.b = 2;
  }
  return obj;
}

答案 6 :(得分:0)

这个怎么样:

function create(includeB) {
    return includeB && { a:1, b:2 } || { a:1 };
}

includeB为真时,create函数将返回{a:1, b:2}。如果includeB为false,则会返回or之后的任何内容 - 在本例中为{a:1}对象。

create(true)返回{ a:1, b:2 }

create(false)返回{ a:1 }

答案 7 :(得分:0)

下面应该有效。我希望这有帮助。

function create(includeB){

var object = {
    a: 1
};

if (includeB)
    object.b = 2;

return object;

}

答案 8 :(得分:0)

如果您想使用声明来满足相同的要求一次没有太多膨胀,您还可以简单地执行以下操作:

var created = function(includeB) {
    var returnObj = { a : 1 };

    if(includeB) { returnObj.b = 2; }

    return returnObj;
}}(); //automatically runs and assigns returnObj to created