问题描述:
给定一个对象:
let myObject ={"ircEvent":"PRIVMSG","method":"newURI","regex":"^http://.*"};
如何删除属性 regex 以得到以下 myObject?
let myObject ={"ircEvent":"PRIVMSG","method":"newURI"};
解决方案1:
huntsbot.com汇聚了国内外优秀的初创产品创意,可按收入、分类等筛选,希望这些产品与实践经验能给您带来灵感。
要从对象中删除属性(改变对象),您可以这样做:
delete myObject.regex;// or,
delete myObject['regex'];// or,var prop ="regex";
delete myObject[prop];
演示
var myObject = { “ircEvent”: “PRIVMSG”, “method”: “newURI”, “regex”: “^http://.*” };删除 myObject.regex;控制台.log(myObject);
对于有兴趣了解更多相关信息的任何人,Stack Overflow 用户 kangax 在他们的博客 Understanding delete 上写了一篇关于 delete 声明的非常深入的博文。强烈推荐。
如果您想要一个 new 对象,其中包含除一些之外的所有原始键,您可以使用 destructuring。
演示
让 myObject = { “ircEvent”: “PRIVMSG”, “method”: “newURI”, “regex”: “^http://.*” }; const {regex, …newObj} = myObject;控制台.log(newObj); // 没有“正则表达式”键 console.log(myObject); // 保持不变
这是一个很好的方法,但只有当你真的要使用 regex 时才好,否则 eslint 会抱怨一个未使用的变量。
@Loolooii您可以重命名解构赋值中的变量以满足no-unused-vars规则中的argsIgnorePattern。容易解决的问题。
我用这种方法遇到的问题是,如果破坏是在条件内,它会让 ESlint 变得疯狂。
文章不见了——当好的内容消失时,我很伤心,很高兴我们有回程机器:web.archive.org/web/20210224201033/http://perfectionkills.com/… :)
了解删除文章:我发现 URL perfectionkills.com/understanding-delete 有效(没有最后一个斜杠)
解决方案2:
huntsbot.com高效搞钱,一站式跟进超10+任务平台外包需求
JavaScript 中的对象可以被认为是键和值之间的映射。 delete 运算符用于删除这些键,通常称为对象属性,一次一个。
var obj = { myProperty: 1 } console.log(obj.hasOwnProperty(‘myProperty’)) // true 删除 obj.myProperty console.log(obj.hasOwnProperty(‘myProperty’)) // false
delete 运算符不直接释放内存,它不同于简单地将 null 或 undefined 的值分配给属性,因为属性 本身 已从对象中删除。请注意,如果已删除属性的 value 是引用类型(对象),并且程序的另一部分仍然持有对该对象的引用,那么该对象当然不会是垃圾收集,直到所有对它的引用都消失了。
delete 仅适用于描述符将其标记为可配置的属性。
解决方案3:
huntsbot.com – 程序员副业首选,一站式外包任务、远程工作、创意产品分享订阅平台。
老问题,现代答案。使用对象解构这一 ECMAScript 6 功能,它非常简单:
const{ a,...rest }={ a:1, b:2, c:3};
或使用问题示例:
const myObject ={"ircEvent":"PRIVMSG","method":"newURI","regex":"^http://.*"};const{ regex,...newObject }= myObject;
console.log(newObject);
You can see it in action in the Babel try-out editor.
编辑:
要重新分配给同一个变量,请使用 let:
let myObject ={"ircEvent":"PRIVMSG","method":"newURI","regex":"^http://.*"};({ regex,...myObject }= myObject);
console.log(myObject);
如果属性名称不同,即如果我将它放在变量中,我该如何解构?
请参阅下面的答案; stackoverflow.com/a/52301527
为什么这比 delete() 更可取? “现代”并不是一个真正的理由......
我不是说它是,我是在提供另一种选择。尽管 delete 曾经对性能有一些影响,但我认为这已经在本页的其他答案中进行了描述。
@GreenAsJade 您更喜欢这个的一个重要原因是它不会改变原始对象。对于像 React 这样的框架非常重要。我实际上正在寻找一个不会改变原始对象的答案。
解决方案4:
huntsbot.com全球7大洲远程工作机会,探索不一样的工作方式
var myObject = {“ircEvent”: “PRIVMSG”, “method”: “newURI”, “regex”: “^http://.*”};删除 myObject.regex;控制台.log (myObject.regex); // 日志:未定义
这适用于 Firefox 和 Internet Explorer,我认为它适用于所有其他人。
解决方案5:
huntsbot.com聚合了超过10+全球外包任务平台的外包需求,寻找外包任务与机会变的简单与高效。
delete 运算符用于从对象中删除属性。
const obj ={ foo:"bar"};
delete obj.foo;
obj.hasOwnProperty("foo");// false
请注意,对于数组,这与删除元素不同。要从数组中删除元素,请使用 Array#splice 或 Array#pop。例如:
arr;// [0, 1, 2, 3, 4]
arr.splice(3,1);// 3
arr;// [0, 1, 2, 4]
细节
严格来说,JavaScript 中不可能真正删除任何内容。 delete 运算符既不删除对象也不释放内存。相反,它将其操作数设置为 undefined 并操纵父对象以使该成员消失。
let parent ={
member:{ str:"Hello"}};
let secondref = parent.member;
delete parent.member;
parent.member;// undefined
secondref;// { str: "Hello" }
对象未被删除。只有参考是。仅当删除对对象的所有引用时,垃圾收集器才会释放内存。
另一个重要的警告是 delete 运算符不会为您重新组织结构,其结果可能看起来违反直觉。例如,删除数组索引会在其中留下一个“洞”。
let array =[0,1,2,3];// [0, 1, 2, 3]
delete array[2];// [0, 1, empty, 3]
这是因为数组是对象。所以索引与键相同。
let fauxarray ={0:1,1:2, length:2};
fauxarray.__proto__ =[].__proto__;
fauxarray.push(3);
fauxarray;// [1, 2, 3]Array.isArray(fauxarray);// falseArray.isArray([1,2,3]);// true
JavaScript 中不同的内置函数以不同的方式处理带有孔的数组。
for…in 语句将完全跳过空索引。
一个简单的 for 循环将在索引处产生未定义的值。
任何使用 Symbol.iterator 的方法都将为索引处的值返回 undefined。
forEach、map 和 reduce 将简单地跳过丢失的索引,但不会删除它
例子:
let array =[1,2,3];// [1,2,3]
delete array[1];// [1, empty, 3]
array.map(x =>0);// [0, empty, 0]
因此,delete 运算符不应用于从数组中删除元素的常见用例。数组有一个专门的方法来删除元素和重新分配内存:Array#splice() 和 Array#pop。
Array#splice(start[, deleteCount[, item1[, item2[, …]]]])
Array#splice 改变数组,并返回所有移除的索引。 deleteCount 元素从索引 start 中删除,并且 item1, item2… itemN 从索引 start 插入到数组中。如果省略 deleteCount,则 startIndex 中的元素将被删除到数组的末尾。
let a =[0,1,2,3,4]
a.splice(2,2)// returns the removed elements [2,3]// ...and `a` is now [0,1,4]
Array.prototype 上还有一个名称相似但不同的函数:Array#slice。
数组#slice([开始[,结束]])
Array#slice 是非破坏性的,并返回一个新数组,其中包含从 start 到 end 的指示索引。如果 end 未指定,则默认为数组的末尾。如果 end 为正数,则它指定要停止的从零开始的 非包含 索引。如果 end 为负数,它通过从数组末尾倒数指定要停止的索引(例如,-1 将省略最终索引)。如果 end <= start,则结果为空数组。
let a =[0,1,2,3,4]
let slices =[
a.slice(0,2),
a.slice(2,2),
a.slice(2,3),
a.slice(2,5)]// a [0,1,2,3,4]// slices[0] [0 1]- - - // slices[1] - - - - -// slices[2] - -[3]- -// slices[3] - -[2 4 5]
数组#pop
Array#pop 从数组中删除最后一个元素,并返回该元素。此操作更改数组的长度。相反的操作是push
数组#shift
Array#shift 与 pop 类似,不同之处在于它删除了第一个元素。相反的操作是unshift。
解决方案6:
保持自己快人一步,享受全网独家提供的一站式外包任务、远程工作、创意产品订阅服务–huntsbot.com
扩展语法 (ES6)
要完成 Koen’s answer,如果您想使用展开语法删除动态变量,您可以这样做:
常量键 = ‘a’; const { [key]: foo, …rest } = { a: 1, b: 2, c: 3 };控制台.log(foo); // 1 console.log(rest); // { b: 2, c: 3 }
- foo 将是一个值为 a(即 1)的新变量。
扩展答案😇
有几种常见的方法可以从对象中删除属性。 每一种都有自己的优缺点 (check this performance comparison):
Delete Operator
它可读且简短,但是,如果您对大量对象进行操作,它可能不是最佳选择,因为它的性能未优化。
delete obj[key];
Reassignment
它比 delete 快两倍以上,但是该属性未被删除并且可以迭代。
obj[key]=null;
obj[key]=false;
obj[key]= undefined;
Spread Operator
这个 ES6 运算符允许我们返回一个全新的对象,不包括任何属性,而不改变现有对象。缺点是它的性能比上述更差,当您需要一次删除许多属性时不建议使用它。
{[key]: val,...rest }= obj;
这不是删除属性,而是创建一个浅拷贝,而不是跨指定的键和值进行复制。这是一个非常大的区别。
解决方案7:
huntsbot.com精选全球7大洲远程工作机会,涵盖各领域,帮助想要远程工作的数字游民们能更精准、更高效的找到对方。
另一种选择是使用 Underscore.js 库。
请注意,_.pick() 和 _.omit() 都返回对象的副本,并且不直接修改原始对象。将结果分配给原始对象应该可以解决问题(未显示)。
参考:link _.pick(object, *keys)
返回对象的副本,过滤后仅包含白名单键(或有效键数组)的值。
var myJSONObject ={"ircEvent":"PRIVMSG","method":"newURI","regex":"^http://.*"};
_.pick(myJSONObject,"ircEvent","method");=>{"ircEvent":"PRIVMSG","method":"newURI"};
参考:link _.omit(object, *keys)
返回对象的副本,过滤以省略列入黑名单的键(或键数组)。
var myJSONObject ={"ircEvent":"PRIVMSG","method":"newURI","regex":"^http://.*"};
_.omit(myJSONObject,"regex");=>{"ircEvent":"PRIVMSG","method":"newURI"};
对于数组,_.filter() 和 _.reject() 可以以类似的方式使用。
解决方案8:
huntsbot.com高效搞钱,一站式跟进超10+任务平台外包需求
要克隆没有属性的对象:
例如:
let object ={ a:1, b:2, c:3};
我们需要删除 a。
使用明确的道具键: const { a, …rest } = object;对象=休息;使用可变道具键: const propKey = ‘a’; const { [propKey]: propValue, …rest } = object;对象=休息;一个很酷的箭头函数😎: const removeProperty = (propKey, { [propKey]: propValue, …rest }) => rest; object = removeProperty(‘a’, object);对于多个属性 const removeProperties = (object, …keys) => (keys.length ? removeProperties(removeProperty(keys.pop(), object), …keys) : object);
用法
object =removeProperties(object,'a','b')// result => { c: 3 }
或者
const propsToRemove =['a','b']
object =removeProperties(object,...propsToRemove)// result => { c: 3 }
解决方案9:
打造属于自己的副业,开启自由职业之旅,从huntsbot.com开始!
您在问题标题中使用的术语,从 JavaScript 对象中删除属性,可以用一些不同的方式来解释。一种是从整个内存和对象键列表中删除它,另一种是从对象中删除它。正如其他一些答案中提到的那样,delete 关键字是主要部分。假设您的对象如下:
myJSONObject ={"ircEvent":"PRIVMSG","method":"newURI","regex":"^http://.*"};
如果你这样做:
console.log(Object.keys(myJSONObject));
结果将是:
["ircEvent","method","regex"]
您可以从对象键中删除该特定键,例如:
delete myJSONObject["regex"];
那么您使用 Object.keys(myJSONObject) 的对象键将是:
["ircEvent","method"]
但关键是,如果您关心内存并且想要将整个对象从内存中删除,建议在删除键之前将其设置为 null:
myJSONObject["regex"]=null;
delete myJSONObject["regex"];
这里的另一个重点是要小心你对同一对象的其他引用。例如,如果您创建如下变量:
var regex = myJSONObject["regex"];
或者将其添加为指向另一个对象的新指针,例如:
var myOtherObject ={};
myOtherObject["regex"]= myJSONObject["regex"];
然后,即使您从对象 myJSONObject 中删除它,该特定对象也不会从内存中删除,因为 regex 变量和 myOtherObject[“regex”] 仍然具有它们的值。那么我们如何才能确定地从内存中删除对象呢?
答案是删除代码中所有指向该对象的引用,并且不要使用 var 语句创建对该对象的新引用。关于 var 语句的最后一点是我们通常面临的最关键问题之一,因为使用 var 语句会阻止创建的对象被删除。
这意味着在这种情况下,您将无法删除该对象,因为您已通过 var 语句创建了 regex 变量,如果您这样做:
delete regex;//False
结果将是 false,这意味着您的删除语句没有按预期执行。但是,如果您之前没有创建该变量,并且您只有 myOtherObject[“regex”] 作为您的最后一个现有引用,您可以通过删除它来完成此操作,如下所示:
myOtherObject["regex"]=null;
delete myOtherObject["regex"];
换句话说,只要代码中没有指向该对象的引用,JavaScript 对象就会被终止。
更新:
感谢@AgentME:
在删除之前将属性设置为 null 不会完成任何事情(除非对象已被 Object.seal 密封并且删除失败。除非您特别尝试,否则通常不会出现这种情况)。
要获得有关 Object.seal 的更多信息:Object.seal()
解决方案10:
huntsbot.com汇聚了国内外优秀的初创产品创意,可按收入、分类等筛选,希望这些产品与实践经验能给您带来灵感。
ECMAScript 2015(或 ES6)带有内置的 Reflect 对象。可以通过使用目标对象和属性键作为参数调用 Reflect.deleteProperty() 函数来删除对象属性:
Reflect.deleteProperty(myJSONObject,'regex');
这相当于:
delete myJSONObject['regex'];
但是,如果对象的属性不可配置,则不能使用 deleteProperty 函数或 delete 运算符删除它:
let obj =Object.freeze({ prop:"value"});
let success =Reflect.deleteProperty(obj,"prop");
console.log(success);// false
console.log(obj.prop);// value
Object.freeze() 使对象的所有属性都不可配置(除了其他东西)。 deleteProperty 函数(以及 delete operator)在尝试删除它的任何属性时返回 false。如果属性是可配置的,它返回 true,即使属性不存在。
delete 和 deleteProperty 之间的区别在于使用严格模式时:
"use strict";
let obj =Object.freeze({ prop:"value"});Reflect.deleteProperty(obj,"prop");// false
delete obj["prop"];// TypeError: property "prop" is non-configurable and can't be deleted
解决方案11:
huntsbot.com全球7大洲远程工作机会,探索不一样的工作方式
假设您有一个如下所示的对象:
varHogwarts={
staff :[
'ArgusFilch',
'FiliusFlitwick',
'GilderoyLockhart',
'MinervaMcGonagall',
'PoppyPomfrey',...],
students :[
'HannahAbbott',
'KatieBell',
'SusanBones',
'TerryBoot',
'LavenderBrown',...]};
删除对象属性
如果您想使用整个 staff 数组,正确的方法是这样做:
delete Hogwarts.staff;
或者,您也可以这样做:
delete Hogwarts['staff'];
同样,可以通过调用 delete Hogwarts.students; 或 delete Hogwarts[‘students’]; 来删除整个学生数组。
删除数组索引
现在,如果您要删除单个员工或学生,则过程有点不同,因为这两个属性本身都是数组。
如果您知道您的员工的索引,您可以简单地执行以下操作:
Hogwarts.staff.splice(3,1);
如果您不知道索引,您还必须进行索引搜索:
Hogwarts.staff.splice(Hogwarts.staff.indexOf('MinervaMcGonnagall')-1,1);
笔记
虽然从技术上讲,您可以将 delete 用于数组,但在稍后调用例如 Hogwarts.staff.length 时,使用它会导致得到不正确的结果。换句话说,delete 会删除元素,但不会更新 length 属性的值。使用 delete 也会弄乱您的索引。
因此,从对象中删除值时,请始终首先考虑您是在处理对象属性还是在处理数组值,并据此选择适当的策略。
如果您想对此进行试验,可以使用 this Fiddle 作为起点。
原文链接:https://www.huntsbot.com/qa/Wylj/how-do-i-remove-a-property-from-a-javascript-object?lang=zh_CN
huntsbot.com – 高效赚钱,自由工作
版权归原作者 HuntsBot 所有, 如有侵权,请联系我们删除。