什么是...
在这个做反应(使用JSX)代码,什么是它叫什么名字?
<Modal {...this.props} title='Modal heading' animation={false}>
...
操作员在不同环境下的行为会有所不同。在这种情况下,它是@TJ Crowder在下面描述的“ spread”运算符。在不同的上下文中,它也可以是@Tomas Nikodym在下面描述的“休息”运算符。
什么是...
在这个做反应(使用JSX)代码,什么是它叫什么名字?
<Modal {...this.props} title='Modal heading' animation={false}>
...
操作员在不同环境下的行为会有所不同。在这种情况下,它是@TJ Crowder在下面描述的“ spread”运算符。在不同的上下文中,它也可以是@Tomas Nikodym在下面描述的“休息”运算符。
Answers:
那是财产传播符号。它是在ES2018中添加的(用于数组/可迭代对象的版本早于ES2015),但是它在React项目中已经通过翻译长期得到了支持(作为“ JSX传播属性 ”,即使您也可以在其他地方这样做) )。
{...this.props}
将 “自己的”可枚举属性props
作为离散属性散布在Modal
要创建的元素上。例如,如果this.props
包含a: 1
和b: 2
,则
<Modal {...this.props} title='Modal heading' animation={false}>
将与
<Modal a={this.props.a} b={this.props.b} title='Modal heading' animation={false}>
但是它是动态的,因此包括了所有“自有”属性props
。
由于children
是中的“拥有”属性props
,因此传播将包括它。因此,如果出现此内容的组件具有子元素,则将它们传递给Modal
。在开始标签和结束标签之间放置子元素只是语法上的糖-一种children
在开始标签中放置属性的好方法。例:
扩展符号不仅适用于该用例,而且对于创建具有现有对象的大多数(或全部)属性的新对象也很方便-在更新状态时会遇到很多问题,因为您无法修改状态直:
this.setState(prevState => {
return {foo: {...prevState.foo, a: "updated"}};
});
它将替换为this.state.foo
具有与该属性相同的所有属性的新对象,foo
该a
属性变为"updated"
:
children
财产或者他们结合起来?
children
。实验告诉我,您通过称为的属性提供的子代children
将替换为您在开始标记和结束标记之间指定的子代,但是,如果这是未定义的行为,我一定不要依赖它。
如您所知 ...
,称为名称的扩展属性可以扩展表达式。
var parts = ['two', 'three'];
var numbers = ['one', ...parts, 'four', 'five']; // ["one", "two", "three", "four", "five"]
在这种情况下(我要简化一下)。
//just assume we have an object like this:
var person= {
name: 'Alex',
age: 35
}
这个:
<Modal {...person} title='Modal heading' animation={false} />
等于
<Modal name={person.name} age={person.age} title='Modal heading' animation={false} />
简而言之,这很整洁可以说捷径。
这三个点表示ES6中的扩展运算符。它使我们可以用Javascript做很多事情:
串联数组
var shooterGames = ['Call of Duty', 'Far Cry', 'Resident Evil'];
var racingGames = ['Need For Speed', 'Gran Turismo', 'Burnout'];
var games = [...shooterGames, ...racingGames];
console.log(games) // ['Call of Duty', 'Far Cry', 'Resident Evil', 'Need For Speed', 'Gran Turismo', 'Burnout']
解构数组
var shooterGames = ['Call of Duty', 'Far Cry', 'Resident Evil'];
var [first, ...remaining] = shooterGames;
console.log(first); //Call of Duty
console.log(remaining); //['Far Cry', 'Resident Evil']
结合两个对象
var myCrush = {
firstname: 'Selena',
middlename: 'Marie'
};
var lastname = 'my last name';
var myWife = {
...myCrush,
lastname
}
console.log(myWife); // {firstname: 'Selena',
// middlename: 'Marie',
// lastname: 'my last name'}
这三个点还有另一种用法,称为“ 休息参数”(Rest Parameters),它可以将函数的所有参数合并为一个数组。
函数参数作为数组
function fun1(...params) {
}
JavaScript中的三个点是传播/休息运算符。
点差运算符
该价差语法允许表达在多个参数预期的地方进行扩展。
myFunction(...iterableObj);
[...iterableObj, 4, 5, 6]
[...Array(10)]
休息参数
的其余参数语法用于与可变参数数目的功能。
function(a, b, ...theArgs) {
// ...
}
ES6中引入了数组的散布/余数运算符。对于对象散布/静止属性,有一个状态2 建议。
TypeScript还支持传播语法,并且可以将其转换为ECMAScript的较早版本,而出现一些小问题。
这是ES6的功能,该功能也用在React中。看下面的例子:
function Sum(x,y,z) {
return x + y + z;
}
console.log(Sum(1,2,3)); //6
如果我们最多有3个参数,则这种方法很好。但是,如果我们需要添加例如110个参数,该怎么办。我们是否应该全部定义并一一添加?
当然,有一种更简单的方法,称为SPREAD。无需传递所有这些参数,而是编写:
function (...numbers){}
我们不知道我们有多少个参数,但是我们知道有很多参数。基于ES6,我们可以如下重写上述功能,并使用它们之间的扩展和映射使它像蛋糕一样容易:
let Sum = (...numbers) => {
return numbers.reduce((prev, current) => prev + current );
}
console.log(Sum(1, 2, 3, 4, 5, 6, 7, 8, 9));//45
它只是为您在JSX中以不同的方式定义道具!
它...
在ES6中使用数组和对象运算符(尚不完全支持对象一),因此,基本上,如果您已经定义了props,则可以将其传递给元素。
因此,在您的情况下,代码应如下所示:
function yourA() {
const props = {name='Alireza', age='35'};
<Modal {...props} title='Modal heading' animation={false} />
}
因此,您定义的道具现已分离,可以在必要时重复使用。
等于:
function yourA() {
<Modal name='Alireza' age='35' title='Modal heading' animation={false} />
}
以下是React团队关于JSX中的传播算子的引文:
JSX传播属性如果您提前知道要放置在组件上的所有属性,则使用JSX很容易:
var component = <Component foo={x} bar={y} />;
更改道具很不好,
如果您不知道要设置哪些属性,可能会在以后将它们添加到对象中:
var component = <Component />;
component.props.foo = x; // bad
component.props.bar = y; // also bad
这是一种反模式,因为这意味着我们要等到以后才能帮助您检查正确的propTypes。这意味着您的propTypes错误最终会导致隐秘的堆栈跟踪。
道具应该被认为是不变的。将props对象突变到其他地方可能会导致意外的结果,因此理想情况下,此时将其冻结。
传播属性
现在,您可以使用JSX的一项新功能,即传播属性:
var props = {};
props.foo = x;
props.bar = y;
var component = <Component {...props} />;
您传递的对象的属性将复制到组件的道具上。
您可以多次使用它,也可以将其与其他属性结合使用。规格顺序很重要。后来的属性将覆盖先前的属性。
var props = { foo: 'default' };
var component = <Component {...props} foo={'override'} />;
console.log(component.props.foo); // 'override'
奇怪的...符号是什么?
ES6中的数组已经支持...运算符(或散布运算符)。还有一个ECMAScript建议书,涉及对象剩余和传播属性。我们利用这些受支持和正在开发的标准,以便在JSX中提供更简洁的语法。
对于那些来自Python世界的人来说,JSX Spread属性等效于
Unpacking Argument Lists(Python操作**
符)。
我知道这是一个JSX问题,但是使用类比有时可以帮助使其更快。
它允许将数组表达式或字符串或任何可以迭代的内容扩展到期望零个或多个参数用于函数调用或数组元素的地方。
var arr1 = [1,2,3];
var arr2 = [4,5,6];
arr1 = [...arr1, ...arr2];
console.log(arr1); //[1, 2, 3, 4, 5, 6]
var arr = [1, 2, 3];
var arr2 = [...arr];
console.log(arr); //[1, 2, 3]
注意:传播语法在复制数组时有效地深入了一层。因此,如下面的示例所示,它可能不适合复制多维数组(与Object.assign()和spread语法相同)。
var arr1 = [4,5]
var arr2 = [1,2,3,...arr1,6]
console.log(arr2); // [1, 2, 3, 4, 5, 6]
var dateFields = [1970, 0, 1]; // 1 Jan 1970
var d = new Date(...dateFields);
console.log(d);
var obj1 = { foo: 'bar', x: 42 };
var obj2 = { foo: 'baz', y: 13 };
var clonedObj = { ...obj1 };
console.log(clonedObj); //{foo: "bar", x: 42}
var mergedObj = { ...obj1, ...obj2 };
console.log(mergedObj); //{foo: "baz", x: 42, y: 13}
请注意,foo
obj1属性已被obj2 foo
属性覆盖
function sum(...theArgs) {
return theArgs.reduce((previous, current) => {
return previous + current;
});
}
console.log(sum(1, 2, 3)); //6
console.log(sum(1, 2, 3, 4)); //10
注意:传播语法(除了传播属性的情况除外)只能应用于可迭代对象: 因此,以下操作将引发错误
var obj = {'key1': 'value1'};
var array = [...obj]; // TypeError: obj is not iterable
感谢布兰登·莫雷利。他在这里完美地解释了,但是链接可能会消失,所以我只粘贴以下内容:
扩展语法仅是三个点:...
它允许迭代器在期望0+参数的地方扩展。没有上下文就很难定义。让我们探索一些不同的用例,以帮助理解这意味着什么。
Example#1 —插入数组 看下面的代码。在这段代码中,我们不使用传播语法:
var mid = [3, 4];
var arr = [1, 2, mid, 5, 6];
console.log(arr);
上面,我们创建了一个名为的数组mid
。然后,我们创建另一个包含mid
数组的数组。最后,我们注销结果。您希望arr
打印什么?点击上方的运行以查看会发生什么。这是输出:
[1, 2, [3, 4], 5, 6]
那是您期望的结果吗?通过将mid
数组插入到arr
数组中,我们最终得到了数组中的一个数组。如果那是目标,那就很好。但是,如果只需要一个值从1到6的数组怎么办?为此,我们可以使用传播语法!请记住,spread语法允许扩展数组的元素。让我们看下面的代码。一切都一样—除了我们现在使用传播语法将mid
数组插入arr
数组之外:
var mid = [3, 4];
var arr = [1, 2, ...mid, 5, 6];
console.log(arr);
当您按下运行按钮时,结果如下:
[1, 2, 3, 4, 5, 6]
太棒了!还记得上面刚刚阅读的传播语法定义吗?这就是发挥作用的地方。如您所见,当我们创建arr
数组并在数组上使用传播运算符时mid
,mid
数组会扩展,而不仅仅是插入数组。这种扩展意味着将mid
数组中的每个元素都插入到arr
数组中。结果不是嵌套数组,而是一个数字数组,范围从1到6。
示例#2 —数学
JavaScript具有一个内置的数学对象,使我们能够进行一些有趣的数学计算。在此示例中,我们将研究Math.max()
。如果您不熟悉,则Math.max()
返回零或多个数字中的最大值。这里有一些例子:
Math.max();
// -Infinity
Math.max(1, 2, 3);
// 3
Math.max(100, 3, 4);
// 100
如您所见,如果要查找多个数字的最大值,则Math.max()
需要多个参数。不幸的是,您不能简单地使用单个数组作为输入。在使用扩展语法之前,在Math.max()
数组上使用的最简单方法是使用.apply()
var arr = [2, 4, 8, 6, 0];
function max(arr) {
return Math.max.apply(null, arr);
}
console.log(max(arr));
它有效,真的很烦。现在看一下我们如何使用传播语法执行相同的操作:
var arr = [2, 4, 8, 6, 0];
var max = Math.max(...arr);
console.log(max);
无需创建函数并利用apply方法返回的结果Math.max()
,我们只需要两行代码!扩展语法扩展了数组元素,并将数组中的每个元素分别输入到Math.max()
方法中!
Example#3 —复制数组 在JavaScript中,您不能仅通过将新变量设置为等于现有数组来复制数组。考虑以下代码示例:
var arr = ['a', 'b', 'c'];
var arr2 = arr;
console.log(arr2);
当您按运行时,您将获得以下输出:
['a', 'b', 'c']
现在,乍一看,它似乎起作用了—看起来我们已经将arr的值复制到了arr2中。但这不是事实。您会看到,使用javascript中的对象(数组是对象的一种类型)时,我们是通过引用而不是值来分配的。这意味着arr2已分配给与arr相同的参考。换句话说,我们对arr2所做的任何操作也会影响原始的arr数组(反之亦然)。看下面:
var arr = ['a', 'b', 'c'];
var arr2 = arr;
arr2.push('d');
console.log(arr);
上面,我们将新元素d放入了arr2中。但是,当我们注销arr的值时,您会看到d值也被添加到该数组中:
['a', 'b', 'c', 'd']
不用担心!我们可以使用点差运算符!考虑下面的代码。与上面几乎相同。相反,我们在一对方括号内使用了散布运算符:
var arr = ['a', 'b', 'c'];
var arr2 = [...arr];
console.log(arr2);
点击运行,您将看到预期的输出:
['a', 'b', 'c']
在上面,arr中的数组值扩展为单个元素,然后将其分配给arr2。现在,我们可以根据需要任意更改arr2数组,而不会对原始arr数组造成任何影响:
var arr = ['a', 'b', 'c'];
var arr2 = [...arr];
arr2.push('d');
console.log(arr);
同样,之所以起作用,是因为将arr的值扩展为填充我们的arr2数组定义的括号。因此,我们将arr2设置为等于arr的各个值,而不是像在第一个示例中所做的那样对arr的引用。
附加示例—从字符串到数组 作为最后一个有趣的示例,您可以使用传播语法将字符串转换为数组。只需在一对方括号内使用传播语法即可:
var str = "hello";
var chars = [...str];
console.log(chars);
这三个点(...)
称为散布运算符,这在概念上类似于ES6阵列散布运算符,JSX利用这些受支持的标准和正在开发的标准来在JSX中提供更简洁的语法
对象初始化程序中的传播属性将自己的可枚举属性从提供的对象复制到新创建的对象上。
let n = { x, y, ...z }; n; // { x: 1, y: 2, a: 3, b: 4 }
参考:
1)https://github.com/sebmarkbage/ecmascript-rest-spread#spread-properties
...的含义取决于您在代码中的使用位置,
const numbers = [1,2,3];
const newNumbers = [...numbers, 4];
console.log(newNumbers) //prints [1,2,3,4]
const person = {
name: 'Max'
};
const newPerson = {...person, age:28};
console.log(newPerson); //prints {name:'Max', age:28}
const filter = (...args) => {
return args.filter(el => el ===1);
}
console.log(filter(1,2,3)); //prints [1]
这是一个传播算子...
例如,如果您有一个数组first=[1,2,3,4,5]
和另一个second=[6,7,8]
。
[...first, ...second] //result is [1,2,3,4,5,6,7,8]
json对象也可以这样做。
简而言之,这三个点...
是ES6(ES2015)中的散布运算符。Spread运算符将获取所有数据。
let a = [1, 2, 3, 4];
let b = [...a, 4, 5, 6];
let c = [7,8,...a];
console.log(b);
将给出结果[1,2,3,4,5,6]
console.log(c);
将给出结果[7,8,1,2,3,4]
用于以简单方式传递多个属性的扩展属性
{... this.props}拥有this.props的属性
将{...} Spread运算符与以下props一起使用
this.props = { firstName: 'Dan', lastName: 'Abramov', city: 'New York', country: 'USA' }
没有{...}传播
<Child firstName={this.props.firstName} lastName={this.props.lastName} city={this.props.city} country={this.props.country} >
随着{...}传播
<Child { ...this.props } />
...此语法是ES6的一部分,不是只能在React中使用的语法,可以两种不同的方式使用;您可以在本文中找到更多信息:https : //www.techiediaries.com/react-spread-operator-props-setstate/
您在问题中提到的是这样的,让我们假设这样,
function HelloUser() {
return <Hello Name="ABC" City="XYZ" />;
}
使用散布运算符,您可以像这样将道具传递给组件。
function HelloUser() {
const props = {Name: 'ABC', City: 'XYZ'};
return <Hello {...props} />;
}
通常在React应用程序中传递道具。通过这样做,我们可以将状态更改应用于子组件,而不管它是纯组件还是不纯组件(无状态或有状态)。有时候,传递道具时最好的方法是传递单个属性或整个属性对象。有了ES6中对数组的支持,我们得到了“ ...”符号,有了它,我们现在能够实现将整个对象传递给孩子。
使用以下语法记录将道具传递给孩子的典型过程:
var component = <Component foo={x} bar={y} />;
当道具的数量最小时,可以使用此方法,但是当道具的数量过多时,将变得难以管理。当您不知道子组件内所需的属性并且典型的JavaScript方法是简单地设置这些属性并在以后绑定到该对象时,就会出现此方法的问题。这会导致propType检查和隐式堆栈跟踪错误等问题无济于事,并会导致调试延迟。以下是此做法的示例以及不应该做的事情:
var component = <Component />;
component.props.foo = x; // bad
component.props.bar = y;
通过执行以下操作,可以达到相同的结果,但取得的成功更大:
var props = {};
props.foo = x;
props.bar = y;
var component = Component(props); // Where did my JSX go?
但是不使用JSX Spread或JSX,因此要将其循环回方程式,我们现在可以执行以下操作:
var props = {};
props.foo = x;
props.bar = y;
var component = <Component {...props} />;
“ ... props”中包含的属性为foo:x,bar:y。可以将其与其他属性组合以使用以下语法覆盖“ ... props”的属性:
var props = { foo: 'default' };
var component = <Component {...props} foo={'override'} />;
console.log(component.props.foo); // 'override'
另外,我们可以将其他属性对象彼此复制或以这种方式组合它们:
var oldObj = { foo: 'hello', bar: 'world' };
var newObj = { ...oldObj, foo: 'hi' };
console.log(newObj.foo); // 'hi';
console.log(newObj.bar); // 'world';
或像这样合并两个不同的对象(尚不能在所有react版本中使用):
var ab = { ...a, ...b }; // merge(a, b)
根据Facebook的react / docs网站,另一种解释方式是:
如果您已经具有“ props”作为对象,并且想要在JSX中传递它,则可以使用“ ...”作为SPREAD运算符来传递整个props对象。以下两个示例是等效的:
function App1() {
return <Greeting firstName="Ben" lastName="Hector" />;
}
function App2() {
const props = {firstName: 'Ben', lastName: 'Hector'};
return <Greeting {...props} />;
}
当您构建通用容器时,传播属性会很有用。但是,它们还可以通过轻松地将许多无关的道具传递给不需要它们的组件来使您的代码混乱。应谨慎使用此语法。
其称为传播算子。例如,让hello = {name:'',msg:''}让hello1 = {... hello}现在hello对象的属性被复制到hello1。
它在javascript中称为“传播语法”。
它用于破坏JavaScript中的数组或对象。
例:
const objA = { a: 1, b: 2, c: 3 }
const objB = { ...objA, d: 1 }
/* result of objB will be { a: 1, b: 2, c: 3, d: 1 } */
console.log(objB)
const objC = { ....objA, a: 3 }
/* result of objC will be { a: 3, b: 2, c: 3, d: 1 } */
console.log(objC)
您可以使用Object.assign()
javascript中的函数执行相同的结果。
参考:传播语法
它将被编译成:
React.createElement(Modal, { ...this.props, title: "Modal heading", animation: false }, child0, child1, child2, ...)
它提供了两个以上的属性title
,animation
超出props
了host元素的范围。
...
是称为Spread的ES6运算符。
参见https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax
扩展运算符(triple operator)在ecama脚本6(ES6)中进行了介绍。Ecama脚本(ES6)是javascript的包装。
在prop中传播运算符的可枚举属性。this.props = {firstName:“ Dan”,lastName:“ Abramov”,城市:“ New York”,国家:“ USA”}
{... this.props} = {firstName:“ Dan”,lastName:“ Abramov”,城市:“ New York”,国家:“ USA”}
但是主要功能扩展运算符用于参考类型。
For example
let person= {
name: 'Alex',
age: 35
}
person1= person;
person1.name = "Raheel";
console.log( person.name); // output: Raheel
这称为引用类型,一个对象会影响其他对象,因为它们可以在内存中共享。如果您独立获得价值,则意味着都使用了扩展内存。
let person= {
name: 'Alex',
age: 35
}
person2 = {...person};
person2.name = "Shahzad";
console.log(person.name); // output: Alex
如果您有一个元素数组并且想要显示这些元素,则只使用... arrayemaments,它将遍历所有元素
...
(Javascript中的三个点)称为“扩展语法”或“扩展运算符”。这允许将可迭代对象(例如数组表达式或字符串)扩展或将对象表达式扩展到任何位置。这不是特定于React的。它是一个Javascript运算符。
所有这些答案在这里都很有帮助,但是我想列举一下传播语法(Spread Operator)中最常用的实用用例。
1.合并数组(连接数组)
有多种组合数组的方法,但是散布运算符允许您将其放置在数组中的任何位置。如果要合并两个数组并将元素放置在数组中的任何位置,可以执行以下操作:
var arr1 = ['two', 'three'];
var arr2 = ['one', ...arr1, 'four', 'five'];
// arr2 = ["one", "two", "three", "four", "five"]
2.复制数组
当我们想要一个数组的副本时,我们曾经拥有Array.prototypr.slice()方法。但是,您可以使用传播运算符执行相同操作。
var arr = [1,2,3];
var arr2 = [...arr];
// arr2 = [1,2,3]
3.调用函数而不应用
在ES5中,要将两个数字组成的数组传递给doStuff()
函数,通常使用Function.prototype.apply()方法,如下所示:
function doStuff (x, y, z) { }
var args = [0, 1, 2];
// Call the function, passing args
doStuff.apply(null, args);
但是,通过使用传播运算符,您可以将数组传递到函数中。
doStuff(...args);
4.解构数组
您可以根据需要使用解构和rest运算符将信息提取到变量中:
let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
console.log(x); // 1
console.log(y); // 2
console.log(z); // { a: 3, b: 4 }
5.函数参数作为休息参数
ES6还具有三个点(...),这是一个rest参数,它将函数的所有剩余参数收集到数组中。
function f(a, b, ...args) {
console.log(args);
}
f(1,2,3,4,5);
// [ 3, 4, 5 ]
6.使用数学函数
可以接受任意数量参数的函数都可以使用将spread用作参数的任何函数。
let numbers = [9, 4, 7, 1];
Math.min(...numbers); // 1
7.结合两个对象
您可以使用散布运算符组合两个对象。这是一种简单而干净的方法。
var carType = {
model: 'Toyota',
yom: '1995'
};
var carFuel = 'Petrol';
var carData = {
...carType,
carFuel
}
console.log(carData);
// {
// model: 'Toyota',
// yom: '1995',
// carFuel = 'Petrol'
// }
8.将字符串分隔为单独的字符
您可以使用传播运算符将字符串传播为单独的字符。
let chars = ['A', ...'BC', 'D'];
console.log(chars); // ["A", "B", "C", "D"]
您可以想到更多使用Spread运算符的方法。我在这里列出的是它的流行用例。
这是ES6 / Harmony中的新功能。它称为扩展运算符。它使您可以分离数组/对象的组成部分,也可以采用多个项目/参数并将它们粘合在一起。这是一个例子:
let array = [1,2,3]
let array2 = [...array]
// array2 is now filled with the items from array
并带有对象/键:
// lets pass an object as props to a react component
let myParameters = {myKey: 5, myOtherKey: 7}
let component = <MyComponent {...myParameters}/>
// this is equal to <MyComponent myKey=5 myOtherKey=7 />
真正很酷的是,您可以用它来表示“其余的值”。
const myFunc = (value1, value2, ...values) {
// Some code
}
myFunc(1, 2, 3, 4, 5)
// when myFunc is called, the rest of the variables are placed into the "values" array