当前位置: 首页 > 知识库问答 >
问题:

对象排列与对象分配

梁宏才
2023-03-14

假设我有一个选项变量,我想设置一些默认值。

这两种选择的好处/缺点是什么?

使用对象传播

options = {...optionsDefault, ...options};

或者用Object.assign

options = Object.assign({}, optionsDefault, options);

这就是让我好奇的promise。

共有3个答案

陈博容
2023-03-14

我认为spread操作符和Object.assign之间的一个很大区别是,spread操作符不会将源对象的原型复制到目标对象,而当前的答案中似乎没有提到这一点。如果要向对象添加属性而不想更改其实例,则必须使用object.assign

编辑:我已经意识到我的例子是误导性的。spread运算符对对象进行消谐。将第一个参数设置为空对象时,将其分配给。在下面的代码示例中,我将error作为对象的第一个参数。assign调用使两者不相等。Object.assign的第一个参数实际上被修改并返回,这就是它保留其原型的原因。我在下面添加了另一个示例:

const error = new Error();
error instanceof Error // true

const errorExtendedUsingSpread = {
  ...error,
  ...{
    someValue: true
  }
};
errorExtendedUsingSpread instanceof Error; // false

// What the spread operator desugars into
const errorExtendedUsingImmutableObjectAssign = Object.assign({}, error, {
    someValue: true
});
errorExtendedUsingImmutableObjectAssign instanceof Error; // false

// The error object is modified and returned here so it keeps its prototypes
const errorExtendedUsingAssign = Object.assign(error, {
  someValue: true
});
errorExtendedUsingAssign instanceof Error; // true

相威
2023-03-14

作为参考,对象Rest/扩散在ECMAScript 2018中作为第4阶段最终确定。建议可以在这里找到。

对于大多数情况,对象重置和排列的工作方式相同,关键区别在于排列定义属性,而object.assign()设置属性。这意味着Object.assign()会触发setter。

值得记住的是,除此之外,对象rest/扩展名1:1映射到Object.assign(),并与数组(可迭代)扩展名不同。例如,当散布数组时,空值被散布。然而,使用对象扩展的空值被无声地扩展为零。

数组(Iterable)扩展示例

const x = [1, 2, null , 3];
const y = [...x, 4, 5];
const z = null;

console.log(y); // [1, 2, null, 3, 4, 5];
console.log([...z]); // TypeError

对象扩展示例

const x = null;
const y = {a: 1, b: 2};
const z = {...x, ...y};

console.log(z); //{a: 1, b: 2}

这与Object.assign()的工作方式一致,两者都默默地排除空值,没有错误。

const x = null;
const y = {a: 1, b: 2};
const z = Object.assign({}, x, y);

console.log(z); //{a: 1, b: 2}
通建安
2023-03-14

这不一定是详尽的。

options = {...optionsDefault, ...options};

>

  • 如果在没有本机支持的环境中编写执行代码,您可能只需要编译此语法(而不是使用polyfill)。(比如巴别塔)

    不那么冗长。

    >

  • 当这个答案最初写出来的时候,这是一个提议,没有标准化。当使用建议时,考虑一下如果你现在用它编写代码,那么它会做什么,而且它不标准化或者随着标准化而改变。自那时以来,这已在ES2018中标准化。

    文字的,不是动态的。

    options = Object.assign({}, optionsDefault, options);
    

    >

  • 标准化。

    动态例子:

    var sources = [{a: "A"}, {b: "B"}, {c: "C"}];
    options = Object.assign.apply(Object, [{}].concat(sources));
    // or
    options = Object.assign({}, ...sources);
    
    • 更详细。
    • 如果编写代码以在没有本机支持的环境中执行,则需要polyfill

    这就是让我好奇的promise。

    这与你的要求没有直接关系。该代码没有使用Object.assign(),而是使用用户代码(Object assign)执行相同的操作。他们似乎在用Babel编译代码(并将其与Webpack捆绑在一起),这就是我所说的:您可以编译的语法。显然,他们更愿意将对象分配作为依赖项包含在构建中。

  •  类似资料:
    • 我有一个过程对象列表,如下所示 我的程序课就像 我想基于以下条件对对象进行排序和分组。 应根据过程名称对所有过程进行分组。 过程必须按过程日期降序排列。[日期列表中的第一个元素,即 分组在一起的相同过程应按日期降序排列。 最终结果必须是, 我能够使用比较器和旧的Java代码实现这一点。是否可以使用java8流、收集器和分组来实现相同的功能?

    • 问题内容: 问题在于确定以下符号之间的权衡: 基于JSON : 基于数组 : 关于同一问题的这篇文章,我已经决定(在前端)使用JSON对象表示法而不是对象数组,因为它符合我的要求,更好的性能和更少的浏览器代码。 但是问题在于列表本身不是静态的。我的意思是,该列表正在生成,即从DB(NoSQL)获取/存储,并通过服务器上的JavaAPI为新条目创建。我无法决定在后端应使用哪种表示法(最终也会影响UI

    • 问题内容: 因此,在标头的c ++文档中,有一个不错的函数可让您对向量进行排序。我上课。我有一个指向该类()对象的指针向量,并且我想通过不同的参数(例如年龄,姓名长度等)来比较人员。 我已经有返回所需变量的函数,但是我不确定该怎么做。这是c ++参考http://www.cplusplus.com/reference/algorithm/sort/中的排序向量函数的链接。 问题答案: 很简单: 然

    • 了解如何在 Adobe XD 中移动、对齐、分布和排列对象。 移动对象 您可以通过以下方式移动对象: 用鼠标拖动对象, 使用键盘上的箭头键,或 在属性检查器中输入精确的数学运算值(+、-、/、*)。 使用 Shift 键来约束一个或多个对象的移动,使其沿相对于当前 x 轴和 y 轴的精确水平或垂直方向移动。  您也可以使用对齐面板,根据对象之间的相对位置来对其进行定位。 通过拖动移动对象 选择一个

    • 在处理EL表达式的标识符时,会先判断标识符是否为EL的内置对象,如果为EL的内置对象,则按内置对象来处理,如果不是EL内置对象,则会将表达式中的表示符当成域对象来处理。相当于pageContext.findAttribute方法返回域属性中的相应对象。如果标识符在域中未找到相应的对象,则什么都不会输出,也就是说返回结果为null。 表7.1列出了所有的EL内置对象及其作用。 表7.1 EL内置对象

    • 我使用带thymeleaf 3的Spring靴 我试着展示一个豆子 在我的控制器里我有 在我的车里 在我的位置 在我的胸腺碎片中 当我试图显示这个片段时,我得到 org.attoparser。ParseException:异常评估SpringEL表达式:“cities.id”由:org.springframework.expression.spel引起。SpelEvaluationExceptio