在JavaScript中有条件地在Array中添加元素

时间:2019-05-07 11:31:42

标签: javascript ecmascript-6

当我尝试使用散布运算符有条件地合并两个对象时,当条件为truefalse时,它将起作用:

let condition = false;
let obj1 = { key1: 'value1'}
let obj2 = {
  key2: 'value2',
  ...(condition && obj1),
};

// obj2 = {key2: 'value2'};

当我尝试对数组使用相同的逻辑时,它仅在条件为true时有效:

let condition = true;
let arr1 = ['value1'];
let arr2 = ['value2', ...(condition && arr1)];

// arr2 = ['value2', 'value1']

如果条件为false,则会引发错误:

let condition = false;
let arr1 = ['value1'];
let arr2 = ['value2', ...(condition && arr1)];

// Error

为什么ArrayObject之间的行为不同?

4 个答案:

答案 0 :(得分:43)

当您展开为 array 时,将在对象上调用Symbol.iterator方法。 &&的计算结果是第一个假值(如果所有均为真,则为最后一个真值),因此

let arr2 = ['value2', ...(condition && arr)];

产生

let arr2 = ['value2', ...(false)];

但是false没有Symbol.iterator方法。

您可以改用条件运算符,如果条件为假,则散布一个空数组:

let condition = false;
let arr1 = ['value1'];
let arr2 = ['value2', ...(condition ? arr1 : [])];
console.log(arr2);

(之所以起作用,是因为空数组确实具有Symbol.iterator方法)

对象传播完全不同:它们将自己的可枚举属性从提供的对象复制到新的对象上。 false没有任何自己的可枚举属性,因此不会复制任何内容。

答案 1 :(得分:17)

<input id="test" value="hello"> <script> alert(test.value); </script> 不可传播。

您需要一个可扩展的对象(已实现Symbol.iterator的对象),如果扩展了,则该对象不会返回任何内容。

您可以使用一个空数组作为默认值。即使falsefalsy,也可以使用。

arr

答案 2 :(得分:11)

这是对象文字和数组文字的扩展语法之间的规范差异。

MDN简要提及了here-我强调:

  

传播语法( 传播属性以外的情况 )只能应用于可迭代对象

差异来自EcmaScript 2018规范:

  • 关于对象传播语法,请参见12.2.6.8 Runtime Semantics: PropertyDefinitionEvaluation

    • 它调用CopyDataProperties(object, fromValue, excludedNames),其中 fromValue ToObject包装到一个对象,因此即使 fromValue 是原始的,也变得可迭代像false这样的值。因此,{...false}有效 EcmaScript。
  • 关于数组扩展语法,请参见12.2.5.2 Runtime Semantics: ArrayAccumulation

    • 它仅调用GetValue(spreadRef),而不会进行上述包装。因此,随后对GetIterator的调用将触发原始值的错误,因为它是不可迭代的。因此,[...false]无效 EcmaScript。

答案 3 :(得分:2)

对象示例:

<!DOCTYPE html>
<html lang="en">
<style>
<!--FONTS-->
@import url('https://fonts.googleapis.com/css2?family=Manrope&display=swap');


body{
  overflow-x: hidden !important;
  max-width: 90%;

}
.center {
  display: block;
  margin-left: auto;
  margin-right: auto;
  width: 350px;
}

button {
  width: 127px;
  height: 36px;
  text-align: center;
  border: none;
  background-color: #f2f2f2;
  border-radius: 5px;
  font-size: 13px;
  color: #777;
  font-family: 'Manrope', sans-serif;
  margin: 10px;
}

input {
  border-width: 3px;
  border-color: #f2f2f2;
  display: block;
  margin-left: auto;
  margin-right: auto;
  width: 400px;
  height: 37px;
  text-align: center;
  font-size: 20px;
  border-radius: 50px;
  border-style: solid;
  font-family: 'Manrope', sans-serif;
}

.btn-toolbar {
  display: flex;
  flex-direction: row;
  justify-content: center;

}

.btn-toolbar button:hover {
  background-color: #88888888;
}

ul {
  background-color: #f2f2f2;
  float: left;
  width: 100%;
  display: inline-block;
}

a {
  color: #777;
  display: inline-block;
  font-size: 15px;
  text-decoration: none;
}

a:hover {
  color: green;
}

.column {
  float: left;
}

.footer{
  position:absolute;
  bottom: 0;
  width: 100%;
  font-family: 'Manrope', sans-serif;

}

.header{
  position:absolute;
  top: 0;
  width: 100%;
  font-family: 'Manrope', sans-serif;

}

h1{
  display: flex;
  justify-content: center;
  align-items: center;
}

.fake-input{
  position: relative;
  width: 350px;
  margin-left: auto;
  margin-right: auto;
  margin-top: auto;
  margin-bottom: auto;
}
.fake-input input{
  background-color: #fff;
  display: block;
  width:100%;
  box-sizing: border-box;
}

.fake-input img{
position: absolute;
top: 11px;
left: 10px;
}

.fake-input img#mic{
position: absolute;
left: unset;
right: 10px;
}

</style>
  

    <div class="row">
      <header id="header" class="header">
        <ul style="list-style-type:none;">

          <li>
            <a class="column" href="https://www.google.com">About</a>
          <a class="column" href="https://www.google.com">Store</a>
          <a class="column" href="https://www.google.com">images</a>
          <a class="column" href="https://www.google.com">gmail</a>
          <a class="column" href="https://www.google.com">squares</a>
          <a class="column" href="https://www.google.com">circle</a>
            </li>
        </ul>
      </header>
      <body>
    </div>
    <!-- Google Logo -->
    <div>
        <h1><img style="padding-bottom: 20px; padding-top: 60px;" class="center" id="google-image" src="https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png">
        </h1>
      </div>
    <div>
      <!--Google search bar -->
      <!-- Search input text -->
      <div class="fake-input">
        <input type="text" placeholder="Search Google or type URL" />
        <img id="msgnify" src="https://cdn.pixabay.com/photo/2017/01/13/01/22/magnifying-glass-1976105_1280.png" width=15 />
      
        <img id="mic" src="https://upload.wikimedia.org/wikipedia/commons/thumb/e/e8/Google_mic.svg/833px-Google_mic.svg.png" width=15>
      </div>
      
      
      <br>

      <!-- Search Buttons -->
      <div style="padding-top: 20px;" class="btn-toolbar">
        <button>Google Search</button>
        <button>I'm Feeling Lucky</button>
      </div>
 
    </div>
    <br>
  </body>
    <!-- footer contains link to the respective locations -->
    <div class="row">
      <footer id="footer" class="footer">
        <ul style="list-style-type:none;">

          <li>
            <a class="column" href="https://www.google.com">Advertising</a>
          <a class="column" href="https://www.google.com">Business</a>
          <a class="column" href="https://www.google.com">How Search Works</a>
          <a class="column" href="https://www.google.com">Privacy</a>
          <a class="column" href="https://www.google.com">Terms</a>
          <a class="column" href="https://www.google.com">Settings</a>
            </li>
        </ul>
      </footer>
    </div>
  














</html>

结果:

 const lessonMenuItems = [
  ...(true
    ? [
        {
          value: 'post',
        },
      ]
    : []),
  {
    value: 'assign',
  },
]