当我尝试使用散布运算符有条件地合并两个对象时,当条件为true
或false
时,它将起作用:
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
为什么Array
和Object
之间的行为不同?
答案 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
的对象),如果扩展了,则该对象不会返回任何内容。
您可以使用一个空数组作为默认值。即使false
是falsy,也可以使用。
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',
},
]