JavaScript的“delete”运算符未按预期工作

4

我有一个如下所示的对象:

var doc = {
  local: {
    username: 'admin',
    status: true,
    password: '$2a$08$81Kq7/59ZASHl5k9n5cNvOUSl/HYgpLKZjs66P/OJV8vw.nHW60Ta',
    lastname: 'admin',
    firstname: 'admin',
    email: 'admin@gmail.com',
    datetime_modified: 'TueAug30201623: 10: 56GMT+0530(IST)',
    datetime_created: 'MonAug29201622: 34: 12GMT+0530(IST)'
  },
  roles: [
    'ADMIN',
    'HR'
  ],
  GridOrder: [
    {
      _id: '57e507fce94094be085425c9',
      domainName: 'items'
    }
  ],
  _id: '57c46b0c12907af910167ff5',
  __v: 9
}

现在我想从“doc”中删除属性“GridOrder”。 我尝试使用如下所示的“delete”:
delete doc.GridOrder

同时还有以下内容:

delete doc['GridOrder']

但是什么也没有发生。我也没有收到任何错误提示。

如何从“doc”中删除“GridOrder”。有什么想法吗?


2
delete doc.GridOrder 应该可以工作。此外,js 将它们称为“对象”,而不是“哈希映射”。 - georg
当使用上述代码时,这个操作会按预期工作。但是有可能 a) GridOrder 是使用 Object.defineProperty() 定义的,或者 b) GridOrder 也是存在于对象原型链上的属性?在这两种情况下,delete 操作都会失败。*参见:delete operator - JavaScript | MDN - gfullam
1
我认为你在这个问题上是正确的。它被定义为“a”。有没有建议如何删除它?还能把上面的评论发表为答案吗? - Arun Mohan
@ArunMohan 如果你不知道如何定义它,你可以像这样做:Object.defineProperty(doc, 'GridOrder', {configurable: true}),这将使你能够像你试图做的那样删除它。请查看Object.defineProperty以获取更多信息。 - taguenizy
1
@gfullam 我的意思是,他在调用 defineProperty 的地方应该尽可能更新它。 - taguenizy
显示剩余2条评论
3个回答

2

使对象属性可配置

当使用上述代码时,您的最小示例按预期工作。

根据您的评论,实际上是使用Object.defineProperty()定义了GridOrder,默认情况下创建的是不可配置(即不可删除)的属性。

只需在定义属性GridOrder时将configurable: true传递给Object.defineProperty即可。

var doc = {
  local: {
    username: 'admin',
    status: true,
    password: '$2a$08$81Kq7/59ZASHl5k9n5cNvOUSl/HYgpLKZjs66P/OJV8vw.nHW60Ta',
    lastname: 'admin',
    firstname: 'admin',
    email: 'admin@gmail.com',
    datetime_modified: 'TueAug30201623: 10: 56GMT+0530(IST)',
    datetime_created: 'MonAug29201622: 34: 12GMT+0530(IST)'
  },
  roles: [
    'ADMIN',
    'HR'
  ],
  _id: '57c46b0c12907af910167ff5',
  __v: 9
}

// Objects defined this way cannot be deleted unless `configurable` is set to `true`
Object.defineProperty(
  doc,
  'GridOrder',
  {
    configurable: true, // Defaults to `false`
    value: [
      {
        _id: '57e507fce94094be085425c9',
        domainName: 'items'
      }
    ]
  }
);

console.log('doc.GridOrder: ', doc.GridOrder);
console.log('delete doc.GridOrder: ', delete doc.GridOrder);
console.log('doc.GridOrder: ', doc.GridOrder);

注意事项

如果configurablefalse,这是默认情况,尝试第二次调用defineProperty将导致JavaScript错误...如果将configurable设置为true,则稍后可以再次修改该属性。

JavaScript中的高级对象

如果您无法访问使用defineProperty创建GridOrder的脚本,则无法稍后修改或删除它。

例如,以下操作将失败:

/*
 * Imagine this is provided by some third-party library that you're unable to edit
 */

var doc = {};

// Objects defined this way cannot be modified or deleted because `configurable` defaults to `false`.
Object.defineProperty(
  doc,
  'GridOrder',
  {
    value: [
      {
        _id: '57e507fce94094be085425c9',
        domainName: 'items'
      }
    ]
  }
);

/*
 * Within your script…
 */

console.log('doc.GridOrder: ', doc.GridOrder);
console.log('delete doc.GridOrder: ', delete doc.GridOrder);
console.log('doc.GridOrder: ', doc.GridOrder);

// …attempts to redefine non-configurable properties will fail
Object.defineProperty(
  doc,
  'GridOrder',
  {
    configurable: true
  }
);

console.log('This will never be seen because an Error has been thrown above.');


0

确认您已经访问了正确的对象,然后使用delete命令。

var doc = {
  local: {
    username: 'admin',
    status: true,
    password: '$2a$08$81Kq7/59ZASHl5k9n5cNvOUSl/HYgpLKZjs66P/OJV8vw.nHW60Ta',
    lastname: 'admin',
    firstname: 'admin',
    email: 'admin@gmail.com',
    datetime_modified: 'TueAug30201623: 10: 56GMT+0530(IST)',
    datetime_created: 'MonAug29201622: 34: 12GMT+0530(IST)'
  },
  roles: [
    'ADMIN',
    'HR'
  ],
  GridOrder: [
    {
      _id: '57e507fce94094be085425c9',
      domainName: 'items'
    }
  ],
  _id: '57c46b0c12907af910167ff5',
  __v: 9
}
delete doc.GridOrder;
console.log('doc.GridOrder', doc.GridOrder)
console.log(doc)

编辑

根据评论,您使用Object.defineProperty定义属性时,需要添加{configurable: true},以便可以随意delete

Object.defineProperty(doc,'GridOrder',{configurable:true})即可。

请参考Object.defineProperty


1
不要将“正确”的答案作为“编辑”放在那里,你应该用新的答案替换掉之前的回答。 - user663031
@torazaburo value 默认为未定义。 - taguenizy

0

你应该在严格模式下运行代码,这样删除失败将导致运行时错误,从而更容易发现:

Uncaught TypeError: Cannot delete property 'foo' of #(…)`

这也允许你如果真的想要的话进行 catch

在松散模式下,delete 操作符在失败时将返回 false,因此您可以检查其值以帮助理解正在发生的情况。根据 MDN 文档:

true 适用于除属性为自有不可配置属性的所有情况外,在这种情况下,在非严格模式下返回 false

请注意,仅仅是属性不存在并不是返回 false 或者当然失败的原因。

一位评论者声称:

是否也是存在于对象的原型链上的属性?在这两种情况下,删除都会失败。

不,属性存在于原型中不会导致 delete 失败。它将成功(意味着不会抛出异常,也不会返回 false),但不会执行任何操作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接