7534

给定一个对象:

让myObject={“ircEvent”:“PRIVMSG”,“方法”:“newURI”,“regex”:“^http://.*”};

如何删除属性正则表达式以以下内容结束我的对象?

让myObject={“ircEvent”:“PRIVMSG”,“方法”:“newURI”};
0

39个答案39

重置为默认值
9908

要从对象中删除属性(更改对象),可以使用删除关键字,如下所示:

删除myObject.regex;//或者,删除myObject['regex'];//或者,var prop=“regex”;删除myObject[prop];

演示

var myObject={“ircEvent”:“PRIVMSG”,“方法”:“newURI”,“regex”:“^http://.*”};删除myObject.regex;console.log(myObject);

对于任何有兴趣阅读更多信息的人,Stack Overflow用户袋鼠写了一篇关于删除在他们的博客上发表声明,了解删除。强烈建议使用。

如果你想要新的对象的所有键都是原始的,但有些键除外,您可以使用破坏.

演示

让myObject={“ircEvent”:“PRIVMSG”,“方法”:“newURI”,“regex”:“^http://.*”};//将键regex赋给变量,表示它将不被使用const{regex:_,…newObj}=myObject;console.log(newObj);//没有“regex”键console.log(myObject);//保持不变

14
  • 24
    这是一个很好的方法,但只有当你真正使用正则表达式,否则eslint将投诉未使用的变量。
    – 卢卢伊
    评论 2021年6月11日14:45
  • @Looloii可以在析构化赋值中重命名变量,以满足参数忽略模式在中无需使用的车辆规则。容易解决的问题。 评论 2021年7月27日16:29
  • 4
    我使用这种方法遇到的问题是,如果destruction在一个条件中,它会让ESlint发疯。 评论 2021年8月24日21:56
  • 文章不见了——当好的内容消失时,我很难过,很高兴我们有了回头机:网址:web.archive.org/web/2210224201033/http://perfectionkills.com/:) 评论 2021年12月4日8:03
  • 2
    理解删除文章:我找到了URLperfectionkills.com/understanding-delete网站works(没有最后一个斜杠)
    – 千卡
    评论 2021年12月6日13:55
1125

JavaScript中的对象可以看作键和值之间的映射。这个删除操作符用于一次删除一个键(通常称为对象属性)。

var对象={我的属性:1}console.log(obj.hasOwnProperty('myProperty'))//真删除obj.myPropertyconsole.log(obj.hasOwnProperty('myProperty'))//错误

这个删除运算符不会直接释放内存,它不同于简单地赋值无效的未定义到一个属性,因为属性它本身从对象中删除。请注意,如果价值被删除属性的是一个引用类型(对象),程序的另一部分仍然保存着对该对象的引用,当然,在所有对它的引用消失之前,不会对该对象进行垃圾收集。

删除只适用于描述符将其标记为可配置的属性。

0
425

古老的问题,现代的答案。使用对象破坏ECMA脚本6功能,简单如下:

常数{a,…rest}={a:1,b:2,c:3};

或者使用问题示例:

const myObject={“ircEvent”:“PRIVMSG”,“method”:“newURI”,“regex”:“^http://.*”};const{regex,…newObject}=myObject;console.log(newObject);

你可以在Babel试用版编辑中看到它的实际应用。


编辑:

要重新分配给同一个变量,请使用:

let myObject={“ircEvent”:“PRIVMSG”,“method”:“newURI”,“regex”:“^http://.*”};({regex,…myObject}=myObject);console.log(myObject);
6
  • 如果属性名发生变化,即我在变量中有它,我该如何进行析构化?
    – 谷神星
    评论 2021年9月14日18:02
  • 1
    请参阅下面的答案;stackoverflow.com/a/52301527
    – 科恩。
    评论 2021年9月15日19:48
  • 4
    为什么这比删除()? “现代”并不是真正的原因。。。 评论 2022年1月1日4:52
  • 1
    我不是说是这样,我是在提供一个替代方案。尽管删除过去有一些性能影响,我认为已经在本页的其他答案中进行了描述。
    – 科恩。
    评论 2022年1月2日8:26
  • 21
    @GreenAsJade你喜欢这个的一个重要原因是它不会改变原始对象。对于React这样的框架非常重要。实际上,我正在寻找一个不会改变原始对象的答案。
    – 西立酮
    评论 2022年7月14日15:09
321

var myObject={“ircEvent”:“PRIVMSG”,“method”:“newURI”,“regex”:“^http://.*”};删除myObject.regex;console.log(myObject.regex);//日志:未定义

这在Firefox和Internet Explorer中有效,我认为它在所有其他应用中都有效。

0
302

这个删除运算符用于从对象中删除属性。

const-obj={foo:“bar”};删除obj.foo;obj.hasOwnProperty(“foo”);//

注意对于阵列,这与删除元素不同。要从数组中删除元素,请使用阵列#拼接数组#pop例如:

arr;//[0, 1, 2, 3, 4]棱缝(3,1);//arr;//[0, 1, 2, 4]

细节

严格地说,不可能真正删除JavaScript中的任何内容。这个删除运算符既不删除对象也不释放内存。相反,它将其操作数设置为未定义并操纵父对象,使成员消失。

让父级={成员:{str:“Hello”}};让secondref=parent.member;删除parent.member;父成员;//未定义secondref;//{str:“你好”}

这个对象未删除。只有引用是。内存只被释放当删除对对象的所有引用时,由垃圾收集器执行。

另一个重要的警告是删除操作员不会为您重新组织结构,这可能会产生违反直觉的结果。例如,删除数组索引会在其中留下一个“洞”。

设数组=[0,1,2,3];//[0, 1, 2, 3]删除数组[2];//[0,1,空,3]

这是因为阵列物体。因此,索引与键相同。

设fauxarray={0:1,1:2,长度:2};福萨雷__原型=[]__原型_;推(3);阵列;//[1, 2, 3]Array.isArray(数组);//数组.isArray([1,2,3]);//真的

JavaScript中的不同内置函数以不同的方式处理带有孔的数组。

  • 用于。。在里面语句将完全跳过空索引。

  • 天真对于循环将产生未定义用于索引处的值。

  • 任何使用的方法符号标识符将返回未定义用于索引处的值。

  • 对于每个,地图减少将跳过缺失的索引,但不会将其移除

例子:

让数组=[1,2,3];//[1,2,3]删除数组[1];//[1,空,3]array.map(x=>0);//[0,空,0]

所以删除运算符不应用于从数组中删除元素的常见用途。数组具有删除元素和重新分配内存的专用方法:阵列#拼接()数组#pop.

阵列#拼接(start[,deleteCount[,item1[,item2[,…]]])

阵列#拼接改变数组,并返回任何删除的索引。删除计数从索引中删除元素开始、和第1项,第2项…第N项从索引插入到数组中开始.如果删除计数则startIndex中的元素被删除到数组的末尾。

设a=[0,1,2,3,4]a.splice(2,2)//返回删除的元素[2,3]// ...现在`a`是[0,1,4]

上还有一个名称类似但不同的函数阵列原型:数组#切片.

数组#切片([begin[,end]])

数组#切片是非破坏性的,并返回一个新数组,其中包含开始结束.如果结束未指定,则默认为数组的末尾。如果结束为正,则指定基于零的非决定性的要停止的索引。如果结束为负,它通过从数组末尾倒数来指定要停止的索引(例如-1将忽略最终索引)。如果结束<=开始,结果是一个空数组。

设a=[0,1,2,3,4]let切片=[a.切片(0,2),a.切片(2,2),a.切片(2,3),a.切片(2,5)]//a[0,1,2,3,4]//切片[0][0 1]--//切片[1]----//切片[2]-[3]--//切片[3]-[2 4 5]

数组#pop

数组#pop从数组中删除最后一个元素,并返回该元素。此操作更改数组的长度。相反的操作是

数组#shift

数组#shift类似于流行音乐,但它删除了第一个元素。相反的操作是取消移位.

0
277

Spread语法(ES6)

完成科恩的回答,如果要使用扩展语法删除动态变量,可以这样做:

常量键=“a”;const{[key]:foo,…rest}={a:1,b:2,c:3};console.log(foo);//1console.log(rest);//{b:2,c:3}

*foo公司将是一个新变量,其值为(即1)。


扩展答案😇

有几种常见的方法可以从对象中删除属性(或将其作为属性进行寻址)。
每一种都有其利弊(检查此性能比较):

删除操作员

它易读且简短。然而,如果您在大量对象上操作,它可能不是最佳选择,因为它的性能没有优化。

删除对象[键];

重新分配

在某些情况下,它可能很方便。它比删除运算符,但键和值都是删除并可以迭代(或跳过)。

obj[key]=空;obj[key]=假;obj[key]=未定义;

排列运算符

这个欧洲标准6操作符允许我们返回一个全新的对象,不包括任何属性,而不改变现有对象。缺点是,它的性能是上述中最差的,当您需要一次删除许多属性时,不建议使用它。

{[key]:val,…rest}=obj;
2
  • 5
    这不是删除属性,而是创建一个浅层副本,而不是跨指定的键和值进行复制。这是一个很大的区别。
    – 罗布·G
    评论 2020年10月30日5:40
  • 这是一个很好的答案,但最后一个例子是荒诞主义。有人问我如何扔掉桌子上一个空的可口可乐瓶,我的回答是订购一张全新的桌子,然后把旧桌子上的所有物品都搬到新桌子上,除了空瓶的可口可乐。你正在创建一组全新的东西,以便去掉这些东西的子集。 评论 2023年2月15日1:28
128

另一种选择是使用下划线.js库。

请注意_.pick()_.omit()两者都返回对象的副本,并且不直接修改原始对象。将结果指定给原始对象应该可以做到这一点(未显示)。

参考:链接 _.pick(对象,*键)

返回对象的副本,已筛选为仅包含白名单键(或有效键数组)。

var myJSON对象={“ircEvent”:“PRIVMSG”,“method”:“newURI”,“regex”:“^http://.*”};_.pick(myJSONObject,“ircEvent”,“method”);=>{“ircEvent”:“PRIVMSG”,“method”:“newURI”};

参考:链接 _.imit(对象,*键)

返回对象的副本,已筛选以忽略列入黑名单的键(或键数组)。

var myJSON对象={“ircEvent”:“PRIVMSG”,“method”:“newURI”,“regex”:“^http://.*”};_.omit(myJSONObject,“regex”);=>{“ircEvent”:“PRIVMSG”,“method”:“newURI”};

对于阵列,_.过滤器()_.reject()可以以类似的方式使用。

1
  • _.imit(obj,“键”)很酷,但我需要省略嵌套键,所以我使用Object.assign(obj,{filters:{sort_by:“”}}) 评论 2022年10月21日18:48
124

要克隆不带属性的对象,请执行以下操作:

例如:

让对象={a:1,b:2,c:3};

我们需要删除.

  1. 使用显式属性键:

    const{a,…rest}=对象;对象=休息;
  2. 用一个可变道具键:

    const propKey='a';const{[propKey]:propValue,…rest}=对象;对象=休息;
  3. A酷箭头函数😎:

    const removeProperty=(propKey,{[propKey]:propValue,…rest})=>rest;object=removeProperty('a',object);
  4. 对于多个属性

    const removeProperties=(object,…keys)=>(keys.length?removeProproperties(removePropert(keys.pop(),object)。。。键):对象);

用法

object=removeProperties(object,'a','b')//result=>{c:3}

或者

const propsToRemove=['a','b']object=removeProperties(object,…propsToRemove)//结果=>{c:3}
1
  • 1
    为避免出现以下警告:参数“propKey”隐式具有“any”类型。ts(7006),为添加类型propKey(属性键)如此:const removeProperty=(propKey:string|number,{[propKey]:propValue,…rest})=>rest
    – A-S公司
    评论 2023年2月9日10:00
82

您在问题标题中使用的术语,从JavaScript对象中删除属性,可以用不同的方式解释。一种是从整个内存和对象键列表中删除它,另一种是只从对象中删除它。正如其他一些回答中提到的那样删除关键词是主要部分。假设您有这样的对象:

myJSONObject={“ircEvent”:“PRIVMSG”,“method”:“newURI”,“regex”:“^http://.*”};

如果您这样做:

console.log(Object.keys(myJSONObject));

结果是:

[“ircEvent”,“method”,“regex”]

您可以从对象关键帧中删除该特定关键帧,如:

删除myJSONObject[“regex”];

然后您的对象使用键Object.keys(myJSONObject)将是:

[“ircEvent”,“方法”]

但关键是,如果您关心内存,并且希望从内存中删除整个对象,建议在删除键之前将其设置为null:

myJSONObject[“regex”]=空;删除myJSONObject[“regex”];

这里的另一个重要点是要注意对同一对象的其他引用。例如,如果您创建一个变量,如:

var regex=myJSONObject[“regex”];

或将其添加为指向其他对象的新指针,如:

var myOtherObject={};myOtherObject[“regex”]=myJSONObject[“regex”];

那么即使你把它从你的物体上移开myJSON对象,该特定对象不会从内存中删除,因为正则表达式变量和myOtherObject[“regex”]仍然有他们的价值观。那么,我们如何从内存中删除对象呢?

答案是删除代码中的所有引用,指向该对象还有不使用变量语句创建对该对象的新引用最后一点是关于变量语句,是我们通常面临的最关键的问题之一,因为使用变量语句将阻止删除创建的对象。

这意味着在这种情况下,您将无法删除该对象,因为您已经创建了正则表达式变量,通过变量声明,如果您这样做:

删除正则表达式//False(错误)

结果是,这意味着您的delete语句没有按预期执行。但如果您以前没有创建该变量myOtherObject[“regex”]作为您最后一个现有的引用,您可以通过如下方式删除它:

myOtherObject[“regex”]=空;删除myOtherObject[“regex”];

换句话说,只要代码中没有指向JavaScript对象的引用,JavaScript对象就有资格被杀死。


更新:

感谢@AgentME:

在删除属性之前将其设置为null无法完成任何东西(除非对象已被object.seal和删除失败。除非你特别指出,否则通常情况并非如此尝试)。

获取更多信息对象.密封:对象密封()

1
  • “只要代码中没有指向该对象的引用,JavaScript对象就会被杀死。”“难道这不应该说”“可以被杀死”“,因为垃圾收集器可以延迟杀死该对象吗?”? 评论 2022年11月14日21:20
57

ECMAScript 2015(或ES6)附带内置反射对象。可以通过调用删除对象属性反射删除属性()以目标对象和属性键作为参数的函数:

Reflect.deleteProperty(myJSONObject,“regex”);

相当于:

删除myJSONObject['regex'];

但是,如果对象的属性不可配置,则既不能使用deleteProperty函数也不能使用deletite运算符删除:

让obj=Object.freeze({prop:“value”});let success=Reflect.deleteProperty(obj,“prop”);console.log(成功);//console.log(obj.prop);//价值

Object.freeze()使对象的所有属性都不可配置(除其他外)。删除属性功能(以及删除运算符)收益当试图删除它的任何属性时。如果属性是可配置的,则返回真的,即使属性不存在。

两者之间的差异删除删除属性使用严格模式时:

“使用严格”;让obj=Object.freeze({prop:“value”});Reflect.deleteProperty(obj,“prop”);//删除对象[“prop”];//TypeError:属性“prop”不可配置,无法删除
0
54

假设您有一个如下所示的对象:

var霍格沃茨={工作人员:[“Argus Filch”,“菲利乌斯·弗利威克”,“Gilderoy Lockhart”,“Minerva McGonagall”,“Poppy Pomfrey”,...],学生:[“Hannah Abbott”,“凯蒂·贝尔”,“Susan Bones”,“Terry Boot”,“薰衣草棕色”,...]};

删除对象属性

如果你想使用整个工作人员数组,正确的方法是这样做:

删除霍格沃茨员工;

或者,您也可以这样做:

删除霍格沃茨['staff'];

类似地,可以通过调用删除霍格沃茨学生;删除霍格沃茨[“学生”];.

删除数组索引

现在,如果您想删除一个教职员工或学生,过程会有所不同,因为这两个属性本身都是数组。

如果您知道员工的索引,您可以简单地这样做:

霍格沃茨员工拼接(3,1);

如果您不知道索引,您还必须进行索引搜索:

霍格沃茨staff.splice(霍格沃兹staff.indexOf(‘米内瓦·麦康纳格尔’)-1);

注释

虽然你在技术上可以使用删除例如,对于数组,使用它将导致在调用时得到错误的结果霍格沃茨员工长度稍后。换句话说,删除将删除元素,但不会更新长度属性。使用删除也会搞乱你的索引。

因此,当从对象中删除值时,始终要首先考虑是处理对象属性还是处理数组值,并基于此选择适当的策略。

如果你想试验这个,你可以使用这个小提琴作为起点。

43

我个人使用下划线.js洛达什对于对象和数组操作:

myObject=_.egnore(myObject,'regex');
40

使用删除方法是实现这一点的最佳方法,根据MDN的描述,delete操作符从对象中删除属性。所以你可以简单地写下:

删除myObject.regex;//或删除myObject['regex'];

delete操作符从对象中删除给定属性。删除成功,则返回true,否则返回false。然而,重要的是要考虑以下场景:

  • 如果要删除的属性不存在,请删除将不起任何作用并返回true
  • 如果对象的原型上存在同名属性链,则删除后,对象将使用原型链(换句话说,删除只对自己有影响属性)。
  • 不能从全局范围中删除任何用var声明的属性或从函数的作用域。
  • 因此,delete不能删除全局范围内的任何函数(无论这是函数定义的一部分还是函数(表达式)的一部分)。
  • 作为对象的一部分的函数(除了
    全局范围)可以使用delete删除。
  • 任何用let或const声明的属性都不能从定义它们的范围中删除。无法删除非配置属性。这包括内置对象(如Math、Array、Object)的属性,以及使用Object.defineProperty()等方法创建为不可配置的属性。

下面的代码片段给出了另一个简单的示例:

var员工={年龄:28岁,name:'Alireza',名称:“开发者”}console.log(删除Employee.name);//返回trueconsole.log(删除Employee.age);//返回true//尝试删除符合以下条件的属性时//不存在,返回trueconsole.log(删除Employee.salary);//返回true

有关更多信息和查看更多示例,请访问以下链接:

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

37

有几种方法可以从对象中删除属性:

1) 使用点属性访问器删除(可变)

const myObject={“ircEvent”:“PRIVMSG”,“方法”:“newURI”,“regex”:“^http://.*”,};删除myObject.regex;console.log(myObject);

2.使用方括号属性访问器删除(可变)

const myObject={“ircEvent”:“PRIVMSG”,“方法”:“newURI”,“regex”:“^http://.*”,};删除myObject['regex'];console.log(myObject);//或const name='ircEvent';删除myObject[名称];console.log(myObject);

3) 通过使用对象析构化和rest语法(不可变),可以在不改变原始对象的情况下删除

const myObject={“ircEvent”:“PRIVMSG”,“方法”:“newURI”,“regex”:“^http://.*”,};const{regex,…myObjectRest}=myObject;console.log(myObjectRest);

35

另一种解决方案,使用数组#减少.

var myObject={“ircEvent”:“PRIVMSG”,“方法”:“newURI”,“正则表达式”:“^http://.*”};myObject=Object.keys(myObject).reduce(函数(obj,key){if(key!=“regex”){//要删除的键obj[key]=myObject[key];}返回对象;}, {});console.log(myObject);

然而,它会突变原始对象。如果要创建新对象没有指定的键,只需将reduce函数分配给一个新变量,例如:

(ES6)

const myObject={ircEvent:'PRIVMSG',方法:“newURI”,正则表达式:“^http://.*”,};const myNewObject=对象.keys(myObject).reduce((obj,key)=>{键!=='正则表达式'?obj[key]=myObject[key]:空;返回对象;}, {});console.log(myNewObject);

30

这里有很多很好的答案,但我只想补充一下,当使用delete删除JavaScript中的属性时,通常明智的做法是首先检查该属性是否存在,以防止出现错误。

例如

var obj={“属性”:“值”,“属性2”:“数值”};if(obj&&obj.hasOwnProperty(“属性2”)){删除对象属性2;}其他{//错误处理}

由于JavaScript的动态特性,经常会出现您根本不知道属性是否存在的情况。检查obj在&&之前是否存在,还可以确保不会因对未定义的对象调用hasOwnProperty()函数而引发错误。

很抱歉,如果这没有添加到您的特定用例中,但我相信这是一个很好的设计,可以在管理对象及其属性时进行调整。

0
26

这篇文章很旧,我觉得它很有用,所以我决定分享我编写的unset函数,以防其他人看到这篇文章,并思考为什么它不像PHP unset函数那么简单。

写这篇新文章的原因未设置函数的作用是保留此hashmap中所有其他变量的索引。看看下面的例子,看看在从hash_map中删除一个值后,“test2”的索引是如何保持不变的。

unset函数(unsetKey、unsetArr、resort){var tempArr=unsetArr;var unsetArr={};删除tempArr[unsetKey];if(度假){j=-1;}for(i in tempArr){if(typeof(tempArr[i])!=='未定义'){if(度假){j++;}其他{j=i;}unsetArr[j]=tempArr[i];}}返回unsetArr;}var unsetArr=['test','deletedString','test2'];console.log(unset('1',unsetArr,true));//输出对象{0:“测试”,1:“测试2”}console.log(unset('1',unsetArr,false));//输出对象{0:“test”,2:“test2”}

20

使用拉姆达#解散您将获得一个没有属性的新对象正则表达式:

const newObject=R.dissoc('regex',myObject);//新对象!==我的对象

您还可以使用其他函数来实现相同的效果-省略、拾取。。。

19

尝试以下方法。分配对象属性值为未定义.然后字符串对象和解析.

var myObject={“ircEvent”:“PRIVMSG”,“method”:“newURI”,“regex”:“^http://.*”};myObject.regex=未定义;myObject=JSON.parse(JSON.stringify(myObject));console.log(myObject);

0
16

使用洛达什

从“lodash/省略”导入省略;const-prevObject={test:false,test2:true};//从上一个对象中删除test2键const nextObject=省略(prevObject,'test2');

使用Ramda

省略(['a','d'],{a:1,b:2,c:3,d:4});//=>{b:2,c:3}
1
  • 奇怪的。您的代码_省略(['a','d'],{a:1,b:2,c:3,d:4});不是为我工作,而是_省略({a:1,b:2,c:3,d:4},['a','d']);做了工作。 评论 2021年11月13日8:05
14

如果要删除对象中深度嵌套的属性,则可以使用以下递归函数,将属性的路径作为第二个参数:

var deepObjectRemove=函数(obj,path_to_key){if(路径to_key.length===1){删除对象[路径to_key[0]];返回true;}其他{if(对象[路径to_key[0]])return deepObjectRemove(对象[path_to_key[0]],路径_to_key.slice(1));其他的返回false;}};

例子:

变量a={级别1:{第2级:{第3级:{级别4:“yolo”}}}};deepObjectRemove(a,[“level1”,“level2”,“level3”]);控制台.log(a);//打印{level1:{level2:{}}}
0
13

Object.assign()&Object.keys()&Array.map()

常量对象={“过滤器”:[{“FilterType”:“介于”,“字段”:“BasicInformationRow.A0”,“最大值”:“2017-10-01”,“最小值”:“2017-09-01”,“Value”:“过滤值”}]};让new_obj1=Object.assign({},obj.Filters[0]);让new_obj2=Object.assign({},obj.Filters[0]);/*//旧版本let shaped_obj1=对象.keys(new_obj1).map((键,索引)=>{开关(钥匙){案例“MaxValue”:删除new_obj1[“最大值”];断裂;案例“MinValue”:删除new_obj1[“最小值”];断裂;}返回new_obj1;})[0];let shaped_obj2=对象.keys(new_obj2).map((键,索引)=>{if(键===“值”){删除new_obj2[“值”];}返回new_obj2;})[0];*///新版本!let shaped_obj1=对象.keys(new_obj1).forEach((键,索引)=>{开关(钥匙){案例“MaxValue”:删除new_obj1[“最大值”];断裂;案例“MinValue”:delete new_obj1[“最小值”];断裂;违约:断裂;}});let shaped_obj2=对象.keys(new_obj2).forEach((键,索引)=>{if(键===“值”){删除new_obj2[“值”];}});

0
13

JavaScript中的属性删除

本页提供了许多不同的选项,并不是因为大多数选项都是错误的,也不是因为答案是重复的,而是因为适当的技巧取决于你所处的情况以及你和/或你的团队试图完成的任务的目标。要明确回答您的问题,您需要知道:

  1. 您的目标ECMAScript版本
  2. 要删除属性的对象类型的范围以及需要忽略的属性名称的类型(仅限字符串?符号?从任意对象映射的弱引用?这些都是JavaScript中多年来的属性指针类型)
  3. 您和您的团队使用的编程精神/模式。你喜欢功能方法吗?在你的团队中,变异是被禁止的吗?还是你采用了西方变异的面向对象技术?
  4. 您希望用纯JavaScript实现这一点吗?或者您愿意并能够使用第三方库吗?

回答完这四个查询后,JavaScript中基本上有四类“属性删除”可供选择,以满足您的目标。他们是:

可变对象属性删除,不安全

当您希望保留/继续使用原始引用并且在代码中不使用无状态函数原则时,此类别用于操作对象文字或对象实例。此类语法示例:

'使用严格'const iLikeMutatingStuffDontI={myNameIs:“KIDDDDD!”,[Symbol.for('amICool')]:true}delete iLikeMuttingStuffDontI[Symbol.for('amICool')]//真对象.defineProperty({myNameIs:'KIDDDDD!','amICool',{value:true,configurable:false})delete iLikeMutatingStuffDontI['amICool']//抛出

该类别是最古老、最直接、最受广泛支持的财产移除类别。它支持符号&除了字符串之外,数组索引也适用于JavaScript的每个版本,除了第一个版本。然而,它是可变的,违反了一些编程原则,并具有性能影响。在上使用时,它还可能导致未捕获的异常严格模式下的非可配置属性.

基于Rest的字符串属性省略

此类别用于在需要非可变方法且不需要考虑符号键时,在较新ECMAScript风格的普通对象或数组实例上操作:

const foo={名称:'KIDDDDD!',[Symbol.for('isCool')]:true}const{name,…coolio}=foo//coolio没有“name”const{isCool,…coolio2}=foo//coolio2包含来自“foo”的所有内容,因为“isCool”不包含符号:(

变异对象属性删除,安全

此类别用于在希望保留/继续使用原始引用的同时防止对不可配置属性引发异常的情况下,对对象文本或对象实例进行操作:

'使用严格'const iLikeMutatingStuffDontI={myNameIs:'KIDDDDD!',[Symbol.for('amICool')]:true}Reflect.deleteProperty(iLikeMutatingStuffDontI,Symbol.for('aICool'))//true对象.defineProperty({myNameIs:'KIDDDDD!','amICool',{value:true,configurable:false})Reflect.deleteProperty(iLikeMutatingStuffDontI,'amICool')//false

此外,虽然就地更改对象不是无状态的,但您可以使用反射删除属性执行部分应用程序和其他无法使用的功能技术删除声明。

基于语法的字符串属性省略

此类别用于在需要非可变方法且不需要考虑符号键时,在较新ECMAScript风格的普通对象或数组实例上操作:

const foo={名称:'KIDDDDD!',[Symbol.for('isCool')]:true}const{name,…coolio}=foo//coolio没有“name”const{isCool,…coolio2}=foo//coolio2包含来自“foo”的所有内容,因为“isCool”不包含符号:(

基于库的属性省略

此类别通常允许更大的功能灵活性,包括考虑符号和在一个语句中省略多个属性:

const o=require(“lodash.imit”)const-foo={[Symbol.for('a')]:'abc',b:'b',c:'c'}const bar=o(foo,'a')//“'a'未定义”const baz=o(foo,[Symbol.for('a'),'b'])//支持符号,一次有多个属性,“Symbol.for('a')undefined”
0
13

丹的断言“删除”的速度非常慢,他发布的基准也受到了质疑。所以我自己用Chrome 59进行了测试。看起来“删除”速度慢了大约30倍:

var iterationsTotal=10000000;//1000万变量o;var t1=日期.now(),t2;for(设i=0;i<iterationsTotal;i++){o={a:1,b:2,c:3,d:4,e:5};删除o.a;删除o.b;删除o.c;删除o.d;删除o.e;}console.log((t2=Date.now())-t1);//6135for(设i=0;i<iterationsTotal;i++){o={a:1,b:2,c:3,d:4,e:5};o.a=o.b=o.c=o.d=o.e=未定义;}console.log(Date.now()-t2);//205

请注意,我故意在一个循环周期中执行多个“删除”操作,以将其他操作造成的影响降至最低。

12

以下是ES6轻松删除条目的方法:

让myObject={“ircEvent”:“PRIVMSG”,“方法”:“newURI”,“正则表达式”:“^http://.*”};const removeItem='regex';const{[removeItem]:删除,…rest}=myObject;console.log(删除);//“^http://.*”console.log(rest);//对象{ircEvent:“PRIVMSG”,方法:“newURI”}

0
11

@约翰斯托克,我们还可以使用JavaScript的原型概念向对象添加方法,以删除调用对象中可用的任何传递键。

感谢以上回答。

var myObject={“ircEvent”:“PRIVMSG”,“方法”:“newURI”,“regex”:“^http://.*”};//第一路和直达路删除myObject.regex;//删除myObject[“regex”]console.log(myObject);//{ircEvent:“PRIVMSG”,方法:“newURI”}//2种方式-使用JavaScript的原型概念Object.prototype.removeFromObjectByKey=函数(键){//如果键存在,请删除它并返回trueif(this[key]!==未定义){删除此[密钥]返回true;}//否则返回false返回false;}var isRemoved=myObject.removeFromObjectByKey(“方法”)console.log(myObject)//{ircEvent:'PRIVMSG'}//更多示例var对象={a: 45岁,b: 第56页,c: 67个}console.log(obj)//{a:45,b:56,c:67}//从obj中删除键“a”isRemoved=obj.removeFromObjectByKey('a')console.log(isRemoved)//真的控制台.log(obj);//{b:56,c:67}//从不存在的obj中删除键“d”var isRemoved=obj.removeFromObjectByKey(d')console.log(已删除);//控制台.log(obj);//{b:56,c:67}

0
11

您可以使用如下过滤器

var myObject={“ircEvent”:“PRIVMSG”,“方法”:“newURI”,“regex”:“^http://.*”};//方式1让过滤器1={}Object.keys({…myObject}).filter(d=>{if(d!==“正则表达式”){filter1[d]=我的对象[d];}})console.log(过滤器1)//方式2let filter2=Object.fromEntries(Object.entries({…myObject}).filter(d=>d[0]!=='正则表达式'))console.log(筛选器2)

  • 但是filter()方法创建了一个数组,其中填充了通过测试的所有数组元素,因此该过滤器的唯一目的是减少并创建一个新数组 评论 2020年9月16日6:15
  • 是的,它是这样做的,但只有当您通过将过滤器的返回值重新指定给原始变量或另一个变量来使用它时,它才有用,而且只有在作为参数传递给它的函数中给它一个返回值时,它才会起作用,但如果在这里完成了这些操作,那么它的唯一作用就是迭代数组元素,这就是forEach的目的 评论 2020年9月16日6:20
  • 2
    你可以这样做let filter=Object.fromEntries(Object.entries(myObject).filter(d=>d!=='regex')) 评论 2020年9月16日6:21
10

我用过Lodash“未设置”使嵌套对象也发生这种情况。。。只需编写小逻辑即可获得属性键的路径省略方法。

  1. 方法,该方法将属性路径作为数组返回

var a={“bool”:{“must”:[{“range”:{:“price_index.final_price”:{'“gt”:“450”,“lt”:“500”}}},{“bool”:}“should”:[[{”term“:{”color_value.keyword“:”Black“}}]}}}}{;函数getPathOfKey(对象,键,当前路径,t){var currentPath=当前路径||[];for(对象中的变量i){如果(i==键){t=当前路径;}else if(对象类型[i]==“对象”){currentPath.push(i)return getPathOfKey(对象[i],键,当前路径)}}t.push(按键);返回t;}document.getElementById(“output”).innerHTML=JSON.stringify(getPathOfKey(a,“price_index.final_price”))
<div id=“output”></div>

  1. 然后使用Lodash未设置方法从对象中移除属性。

var unset=要求('lodash.unset');unset(a,getPathOfKey(a,“price_index.final_price”);

5

让myObject={“ircEvent”:“PRIVMSG”,“方法”:“newURI”,“regex”:“^http://.*”};obj=对象.fromEntries(Object.entries(myObject).filter(函数(m){返回m[0]!=“regex”/*或任何要删除的键*/}))控制台.log(obj)

你也可以像对待物体一样二维数组使用对象条目,并像在普通数组中一样使用splice删除元素,或者像筛选数组一样简单地筛选对象,然后将重建的对象重新分配给原始变量

5

如果不想修改原始对象。

删除属性而不更改对象

如果可变性是一个问题,那么可以通过从旧对象中复制除要删除的属性之外的所有属性来创建一个全新的对象。

让myObject={“ircEvent”:“PRIVMSG”,“方法”:“newURI”,“regex”:“^http://.*”};let prop=“regex”;const-updatedObject=Object.keys(myObject).reduce((Object,key)=>{if(键!==属性){object[key]=myObject[key]}回波信号}, {})console.log(更新对象);

不是你想要的答案吗?浏览已标记的其他问题问你自己的问题.