扩展运算符似乎没有复制完整对象

Posted

技术标签:

【中文标题】扩展运算符似乎没有复制完整对象【英文标题】:spread operator does not seem to copy full object 【发布时间】:2021-01-06 08:24:45 【问题描述】:

我正在尝试实现快速错误处理中间件。它正在工作,但我不明白为什么在将err 复制到error 后,我必须将error.message 设置为等于err.message。扩展运算符是否没有从err 复制所有属性?当我检查 err 对象时,我什至看不到消息或堆栈属性。还有,为什么它能够在if块中创建错误消息之前记录错误消息。

这就是我扩展错误的方式

// src/utils/errorResponse.js

class ErrorResponse extends Error 
  constructor(message, statusCode) 
    super(message)
    this.statusCode = statusCode
  

module.exports = ErrorResponse

自定义错误处理程序中间件

// src/middleware/error.js

const ErrorResponse = require('../utils/errorResponse')

const errorHandler = (err, req, res, next) => 
  let error =  ...err  
  console.log( error.message ) // undefined
  error.message = err.message
  console.log( error.message ) // `Resource not found with id of $err.value`

  // Log to console for dev
  // console.log(error.stack)

  // Mongoose bad ObjectId
  if (err.name === 'CastError') 
    const message = `Resource not found with id of $err.value`
    error = new ErrorResponse(message, 404)
   else 
    console.log(error.name)
  

  res.status(error.statusCode || 500).json(
    success: false,
    error: error.message || 'Server Error',
  )


module.exports = errorHandler

我通过使用错误的 ObjectID 发出 get 请求来触发错误

// src/controllers/bootcamp.js

const Bootcamp = require('../models/Bootcamp')

...

// @desc Get single bootcamp
// @route GET /api/v1/bootcamps/:id
// @access Public
exports.getBootcamp = async (req, res, next) => 
  try 
    const bootcamp = await Bootcamp.findById(req.params.id)
    if (!bootcamp) 
      return next(err)
    
    res.status(200).json( success: true, data: bootcamp )
   catch (err) 
    next(err)
  

【问题讨论】:

【参考方案1】:

发生这种情况是因为您得到的 err 参数属于错误类型对象,并且消息键存在于错误对象的原型中,并且传播运算符浅拷贝对象的键(不包括原型键)

来自 mdn 的扩展运算符的声明 -

ECMAScript 提案 (ES2018) 的 Rest/Spread 属性向对象字面量添加了扩展属性。它将自己的可枚举属性从提供的对象复制到新对象。

现在可以使用比 Object.assign() 更短的语法进行浅层克隆 (excluding prototype) 或对象合并。

供参考-

https://developer.mozilla.org/en-US/docs/Web/javascript/Reference/Global_Objects/Error

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax

【讨论】:

以上是关于扩展运算符似乎没有复制完整对象的主要内容,如果未能解决你的问题,请参考以下文章

ES6扩展运算符(三点运算符)“...”用法和对象拷贝

Babel 无法使用扩展运算符编译 ES6 对象克隆

es6扩展运算符及rest运算符总结

javascript ES6 新特性之 扩展运算符 三个点 ...

JavaScript |扩展运算符更新嵌套值

ES6数组和对象的扩展