【问题标题】:What do these three dots in React do?React 中的这三个点有什么作用?
【发布时间】:2020-06-24 05:13:08
【问题描述】:

... 在这个 React(使用 JSX)代码中做了什么?它叫什么?

<Modal {...this.props} title='Modal heading' animation={false}>

【问题讨论】:

  • 注意:... 运算符在不同的上下文中表现不同。在这种情况下,它是@T.J. 下面描述的“扩展”运算符。克劳德。在不同的上下文中,这也可能是下面@Tomas Nikodym 描述的“休息”运算符。
  • ... 正在将 this.props 数组解构为单独的值

标签: javascript reactjs spread-syntax


【解决方案1】:

那是property spread notation。它是在 ES2018 中添加的(数组/可迭代的传播更早,ES2015),但它在 React 项目中通过转译得到了很长时间的支持(如“JSX spread attributes”,即使你也可以在其他地方做,不仅仅是属性)。

{...this.props} 扩展props 中的“自己的”可枚举属性作为您正在创建的Modal 元素上的离散属性。例如,如果this.props 包含a: 1b: 2,那么

<Modal {...this.props} title='Modal heading' animation={false}>

将与

相同
<Modal a={this.props.a} b={this.props.b} title='Modal heading' animation={false}>

但它是动态的,所以 props 中的任何“自己”属性都包括在内。

由于childrenprops 中的“自己的”属性,spread 将包含它。所以如果这个出现的组件有子元素,它们将被传递给Modal。将子元素放在开始标记和结束标记之间只是语法糖——很好的一种——用于将children 属性放在开始标记中。示例:

class Example extends React.Component {
  render() {
    const { className, children } = this.props;
    return (
      <div className={className}>
      {children}
      </div>
    );
  }
}
ReactDOM.render(
  [
    <Example className="first">
      <span>Child in first</span>
    </Example>,
    <Example className="second" children={<span>Child in second</span>} />
  ],
  document.getElementById("root")
);
.first {
  color: green;
}
.second {
  color: blue;
}
<div id="root"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

扩展符号不仅适用于该用例,而且适用于创建具有现有对象的大部分(或全部)属性的新对象——这在您更新状态时经常出现,因为您可以' t 直接修改状态:

this.setState(prevState => {
    return {foo: {...prevState.foo, a: "updated"}};
});

这会将this.state.foo 替换为具有与foo 相同属性的新对象,但a 属性变为"updated"

const obj = {
  foo: {
    a: 1,
    b: 2,
    c: 3
  }
};
console.log("original", obj.foo);
// Creates a NEW object and assigns it to `obj.foo`
obj.foo = {...obj.foo, a: "updated"};
console.log("updated", obj.foo);
.as-console-wrapper {
  max-height: 100% !important;
}

【讨论】:

  • 在开始标签和结束标签之间放置一个子元素覆盖 children 属性还是它们组合在一起?
  • @anddero - 这是一个非常有趣的问题。据我所见,它是children 中的not covered by [the documentation。实验告诉我,您通过名为 children 的属性提供的子代被您在开始和结束标记之间指定的子代所取代,但如果它是未定义的行为,我一定不要依赖它。跨度>
【解决方案2】:

... 被称为扩展属性,顾名思义,它允许扩展表达式。

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} />

简而言之,这是一个简洁的捷径,我们可以说

【讨论】:

  • var person = { name:'Alex',age:35} 是 json,javascript 对象表示法。 ...person 评估为 name='Alex', age=35 其目的是假设您在 json 结构中有 1,000,000 个这些键值对,并且您想将它们全部传递给组件,您所要做的就是做... 符号,它们都通过了。您不必一一列举。
  • 这不是 ECMA 文档,不要太认真!我首先以这种方式回答了这个问题,过了一会儿,其他人将他们的答案更改为看起来像我的,只是获得了一些投票。
  • 将有助于添加一个将一个对象传播到另一个对象的示例,因为这本质上就是 JSX 传播在幕后所做的。
  • 最佳答案,清晰明了
  • @BMW,我从这个答案中吸取了教训,当我看到其他人复制我的答案并添加到他们自己的答案时,以获得更多积分!即使在 Stackoverflow 之外,这也是一个社会的运作方式。人们只是在寻找数字......
【解决方案3】:

三个点代表ES6 中的扩展运算符。它允许我们在 JavaScript 中做很多事情:

  1. 连接数组

     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']
    
  2. 解构数组

       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']
    
  3. 组合两个对象

     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,它可以将函数的所有参数作为一个数组获取。

  1. 函数参数作为数组

      function fun1(...params) {
    
      }
    

【讨论】:

  • 这是一个很好的答案,因为每个用例都有所有清晰的示例。感谢您抽出宝贵时间写出所有这些内容。
  • 在示例之前提及其余参数以更清晰
  • 不仅是最佳答案,也是最有趣的答案,'Selana Marie 你的初恋:D'
  • 3.5.解构对象
  • 这是一个很棒的答案,作为一名 Python 开发人员,我可以将扩展运算符转换为使用 * 或 ** 表示法的打包/解包,基本上做同样的事情。
【解决方案4】:

JavaScript 中的三个点是 spread / rest 运算符

传播算子

spread syntax 允许在需要多个参数的地方扩展表达式。

myFunction(...iterableObj);

[...iterableObj, 4, 5, 6]

[...Array(10)]

静止参数

rest 参数语法用于具有可变数量参数的函数。

function(a, b, ...theArgs) {
  // ...
}

ES6 中引入了数组的扩展/剩余运算符。对象传播/休息属性有一个状态 2 proposal

TypeScript 还支持扩展语法,并且可以将其转换为带有次要 issues 的旧版 ECMAScript。

【讨论】:

【解决方案5】:

...(JavaScript 中的三个点)称为扩展语法或扩展运算符。这允许在任何位置展开诸如 array 表达式或 string 之类的可迭代对象,或者在任何位置展开 object 表达式。这不是 React 特有的。它是一个 JavaScript 运算符。

这里所有这些答案都很有帮助,但我想列出Spread Syntax(扩展运算符)最常用的实际用例。

1.合并数组(连接数组)

有一个variety of ways to combine arrays,但扩展运算符允许您将其放置在数组中的任何位置。如果您想组合两个数组并将元素放置在数组中的任意位置,您可以执行以下操作:

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.不使用 Apply 调用函数

在 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.解构数组

您可以结合使用解构和其余运算符将信息提取到您想要的变量中:

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.函数参数作为 Rest 参数

ES6 也有三个点 (...),它是一个剩余参数,将函数的所有剩余参数收集到一个数组中。

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"]

您可以想出更多使用展开运算符的方法。我在这里列出的是它的流行用例。

【讨论】:

    【解决方案6】:

    这是 ES6 的一个特性,在 React 中也有使用。看下面的例子:

    function Sum(x, y, z) {
       return x + y + z;
    }
    console.log(Sum(1, 2, 3)); // 6
    

    如果我们最多有三个参数,这种方式就可以了。但是,如果我们需要添加例如 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
    

    【讨论】:

      【解决方案7】:

      感谢 Brandon Morelli。 他完美地解释了 here,但链接可能会失效,所以我只是粘贴以下内容:

      展开语法只是三个点:... 它允许迭代在预期有 0​​+ 个参数的地方扩展。 没有上下文就很难定义。让我们探索一些不同的用例来帮助理解这意味着什么。

      示例 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 的数组呢?为此,我们可以使用扩展语法!请记住,展开语法允许我们数组的元素展开。

      让我们看看下面的代码。一切都一样——除了我们现在使用扩展语法将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() 的结果,我们只需要两行代码! spread 语法扩展了我们的数组元素,并将数组中的每个元素单独输入到Math.max() 方法中!

      示例 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);

      【讨论】:

        【解决方案8】:

        它只是为你在 JSX 中以不同的方式定义 props

        它在 ES6 中使用... 数组和对象运算符(对象一还没有完全支持),所以基本上如果你已经定义了你的道具,你可以通过这种方式将它传递给你的元素。

        所以在你的情况下,代码应该是这样的:

        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 中提供更简洁的语法。

        【讨论】:

        • 你已经回答完了他的问题。
        • 什么是“道具”? “特性”?还是字面意思?
        【解决方案9】:

        三个点... 代表spread operatorsrest parameters

        它允许数组表达式或字符串或任何可以迭代的东西在需要零个或多个函数调用参数或数组元素的地方扩展。

        • 合并两个数组

        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() 和传播语法)。

        • 在特定索引处将一个数组的值添加到另一个数组,例如 3:

        var arr1 = [4, 5]
        var arr2 = [1, 2, 3, ...arr1, 6]
        console.log(arr2);    // [1, 2, 3, 4, 5, 6]
        • 使用 new 调用构造函数时:

        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}

        请注意,obj1 的 foo 属性已被 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

        Reference1

        Reference2

        【讨论】:

        • 您使用三点合并两个数组的第一个示例非常有用。谢谢。
        【解决方案10】:

        对于想要简单快速地理解这一点的人:

        首先,这不仅仅是 React 的语法。这是来自 ES6 的语法,称为 spread syntax,它迭代(合并、添加等)数组和对象。阅读更多关于它的信息here

        所以回答这个问题:

        假设你有这个标签:

        &lt;UserTag name="Supun" age="66" gender="male" /&gt;

        你这样做:

        const user = {
          "name"=>"Joe",
          "age"=>"50"
          "test"=>"test-val"
        };
        
        <UserTag name="Supun" gender="male"  {...user} age="66" />
        

        那么标签就等于这个:

        <UserTag name="Joe" gender="male" test="test-val" age="66" />
        

        因此,当您在 React 标签中使用扩展语法时,它会将标签的属性作为对象属性与给定对象 user 合并(如果存在则替换)。此外,您可能已经注意到一件事,它只替换属性之前,而不是属性之后。所以在这个例子中,年龄保持不变。

        【讨论】:

        • 最后不应该age=50吗?
        • @DonCheadle 不,因为我在年龄之前添加了{...user},所以年龄标签不会替换
        【解决方案11】:

        对于那些来自 Python 世界的人来说,JSX 传播属性相当于 Unpacking Argument Lists(Python **-运算符)。

        我知道这是一个 JSX 问题,但使用类比有时有助于更快地解决问题。

        【讨论】:

          【解决方案12】:

          ...(spread operator) 在 React to 中使用:

          提供一种简洁的方式将 props 从父组件传递到子组件。例如,给定父组件中的这些道具,

          this.props = {
            username: "danM",
            email: "dan@mail.com"
          }
          

          它们可以通过以下方式传递给孩子,

          <ChildComponent {...this.props} />
          

          类似于这个

          <ChildComponent username={this.props.username} email={this.props.email} />
          

          但更干净。

          【讨论】:

          • 假设,如果我们只想将 'username' 属性传递给子组件,那么我们可以使用 吗?
          • 为什么它要求我在 h1 标签中的这个关键字之前使用扩展运算符?类测试 { obj = { user1:“vijay”,年龄:27 }; m1() {

            ; } }
          • //ex-2:对于这个例子,当我使用 img 标签时,它不会抛出错误来使用扩展运算符。类测试 { obj = { user1: "vijay", imageUrl: "picsum.photos/id/1/200/300" }; m1() { //

            ; ; } }
          【解决方案13】:

          三个点(...) 称为扩展运算符,这在概念上类似于 ES6 数组扩展运算符 JSX 利用这些受支持和正在开发的标准,以便在 JSX 中提供更简洁的语法

          对象初始化器中的扩展属性复制自己的可枚举 将提供的对象的属性添加到新创建的对象上。

          let n = { x, y, ...z };
          n; // { x: 1, y: 2, a: 3, b: 4 }
          

          参考资料:

          1. Spread Properties

          2. JSX In Depth

          【讨论】:

          • 这是对 ECMAScript 中对象的扩展运算符的提议。问题是关于 JSX 扩展运算符。尽管它们的工作方式相同,但它们并不相同。
          • @ivarni 感谢您带我进入上下文,给我一点时间,将根据问题上下文更新答案
          • @ivarni 根据上下文更新答案,希望这符合上下文
          • “三个点 (...) 被称为扩展运算符” 只是不正确。 :-) Spread 和 rest 不是运算符,也不能是,因为运算符必须产生单个结果值。 Spread 和 rest 是主要语法,而不是运算符。
          【解决方案14】:

          在 React 应用程序中传递 props 是一种常见的做法。在这样做时,我们能够将状态更改应用于子组件,无论它是纯的还是不纯的(无状态的或有状态的)。有时,在传递 props 时,最好的方法是传递单个属性或整个属性对象。由于 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} />;
          }
          

          当您构建通用容器时,扩展属性会很有用。但是,它们也可以通过轻松将许多不相关的道具传递给不关心它们的组件来使您的代码变得混乱。应谨慎使用此语法。

          【讨论】:

          • “纯”和“不纯”是字面意思吗?为了强调,我们在这个平台上使用了斜体和粗体。
          【解决方案15】:

          在 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)
          

          您可以使用 JavaScript 中的 Object.assign() 函数来实现相同的结果。

          参考:传播syntax

          【讨论】:

            【解决方案16】:

            ECMAScript 6 (ES6) 中引入的扩展运算符(三元运算符)。 ECMAScript (ES6) 是 JavaScript 的包装器。

            props 中的扩展运算符可枚举属性。

            this.props = { 名字:'丹', 姓氏:“阿布拉莫夫”, 城市:“纽约”, 国家:“美国” }

            {...this.props} = { firstName: 'Dan', 姓氏:“阿布拉莫夫”, 城市:“纽约”, 国家:“美国”}

            但主要特征扩展运算符用于引用类型。

            例如,

            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
            

            【讨论】:

              【解决方案17】:

              Spread 运算符可让您将对象、字符串或数组等可迭代对象扩展为其元素,而 Rest 运算符则通过将一组元素缩减为一个数组来进行相反的操作。

              【讨论】:

                【解决方案18】:

                扩展语法允许像数组和对象这样的数据结构解构 他们要么从中提取价值,要么为他们增加价值。 例如 const obj={name:"ram",age:10} const {name}=obj 从上面的示例中,我们可以说我们解构了 obj 并从该对象中提取了名称。 相似地, const newObj={...obj,address:"Nepal"} 在此示例中,我们向该对象添加了一个新属性。 这在数组的情况下也是类似的。

                【讨论】:

                  【解决方案19】:

                  这些称为点差。顾名思义,这意味着它将它的任何值放入那些数组或对象中。

                  如:

                  let a = [1, 2, 3];
                  let b = [...a, 4, 5, 6];
                  console.log(b);
                  > [1, 2, 3, 4, 5, 6]
                  

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 2017-08-06
                    • 1970-01-01
                    • 2016-05-20
                    • 2017-02-09
                    • 1970-01-01
                    • 2011-07-10
                    相关资源
                    最近更新 更多