ฉันจะลบคุณสมบัติออกจากวัตถุ JavaScript ได้อย่างไร


6140

ว่าฉันสร้างวัตถุดังนี้

let myObject = {
    "ircEvent": "PRIVMSG",
    "method": "newURI",
    "regex": "^http://.*"
};

เป็นวิธีที่ดีที่สุดในการลบคุณสมบัติregexเพื่อจบด้วยใหม่myObjectดังนี้

let myObject = {
    "ircEvent": "PRIVMSG",
    "method": "newURI"
};


@EscapeNetscape นี่เป็นคำถามเกี่ยวกับพฤติกรรมดังนั้นมาตรฐานจึงวาดภาพผิด ๆ แน่นอนว่าdeleteจะเป็นตัวเลือกที่ช้าที่สุดเนื่องจากเป็นการดำเนินการจริงแทนที่จะเป็นอีกสองการทำงานที่ได้รับมอบหมายอย่างง่าย แต่ปมของเรื่องคือการกำหนดคุณสมบัติให้nullหรือundefinedไม่ลบคุณสมบัติออกจากวัตถุจริง ๆ แต่แทนที่จะตั้งค่าคุณสมบัตินั้นให้เท่ากับค่าคงที่โดยเฉพาะ (ด้านล่างคำตอบให้เหตุผลว่าทำไมสิ่งนี้จึงแตกต่างอย่างมีนัยสำคัญ)
Abion47

คำตอบ:


8303

แบบนี้:

delete myObject.regex;
// or,
delete myObject['regex'];
// or,
var prop = "regex";
delete myObject[prop];

การสาธิต

var myObject = {
    "ircEvent": "PRIVMSG",
    "method": "newURI",
    "regex": "^http://.*"
};
delete myObject.regex;

console.log(myObject);

สำหรับทุกคนที่สนใจในการอ่านเพิ่มเติมเกี่ยวกับการใช้งานมากเกิน Stack kangaxได้เขียนบล็อกโพสต์อย่างไม่น่าเชื่อในเชิงลึกเกี่ยวกับdeleteคำสั่งเกี่ยวกับบล็อกของพวกเขาทำความเข้าใจลบ ขอแนะนำอย่างยิ่ง


47
ตรวจสอบแล้วมันยังทำงานกับ "ลบ myJSONObject ['regex'];" ดู: developer.mozilla.org/en/Core_JavaScript_1.5_Reference/
......

109
ผลที่สุดของการสังเกตอย่างใดอย่างหนึ่งที่ลิงก์ "การทำความเข้าใจการลบ" ด้านบนคือเนื่องจากคุณไม่สามารถลบตัวแปรได้ แต่มีเพียงคุณสมบัติของวัตถุเท่านั้นคุณจึงไม่สามารถลบคุณสมบัติของวัตถุ "โดยการอ้างอิง" - var value = obj [ 'เสา']; ค่าลบ // ไม่ทำงาน
Dexygen

27
ดังนั้นมันจะไม่ลบจริงเหรอ? มันเพิ่งจะไม่ได้กำหนด แต่กุญแจยังคงมีอยู่? ฉันพลาดอะไรไปรึเปล่า?
Doug Molineux

151
@ ไม่เอามันเอาออก ให้ไว้: var x = {a : 'A', b : 'B'};เปรียบเทียบ: delete x.a; typeof x.a; /* "undefined" */ x.hasOwnProperty('a'); /* false */ถึงx.b = undefined; typeof x.b; /* "undefined" */; x.hasOwnProperty('b'); /* true */
nickf

16
@ChristopherPfohl ได้ผลสำหรับฉัน อย่างที่ฉันพูดมันจริง ๆ แล้วในเชิงลึกดังนั้นจึงค่อนข้างยากที่จะสรุป การตอบสนองขั้นพื้นฐานในคำตอบข้างต้นนั้นเพียงพอสำหรับเกือบทุกกรณีบล็อกเข้าสู่กรณีและปัญหาที่เกิดขึ้น
nickf

952

วัตถุใน JavaScript ถือได้ว่าเป็นแผนที่ระหว่างปุ่มและค่า deleteผู้ประกอบการใช้ในการลบคีย์เหล่านี้เป็นที่รู้จักกันทั่วไปว่าเป็นคุณสมบัติของวัตถุหนึ่งที่เวลา

var obj = {
  myProperty: 1    
}
console.log(obj.hasOwnProperty('myProperty')) // true
delete obj.myProperty
console.log(obj.hasOwnProperty('myProperty')) // false

deleteผู้ประกอบการไม่หน่วยความจำฟรีไม่ได้โดยตรงและมันแตกต่างจากเพียงแค่การกำหนดค่าของnullหรือundefinedคุณสมบัติในว่าทรัพย์สินที่ตัวเองจะถูกลบออกจากวัตถุ โปรดทราบว่าหากค่าของคุณสมบัติที่ถูกลบเป็นประเภทการอ้างอิง (วัตถุ) และอีกส่วนหนึ่งของโปรแกรมของคุณยังคงมีการอ้างอิงไปยังวัตถุนั้นแน่นอนว่าวัตถุนั้นจะไม่ถูกเก็บรวบรวมขยะจนกว่าจะมีการอ้างอิงทั้งหมดที่มี หายไป.

delete จะทำงานกับคุณสมบัติที่ descriptor ทำเครื่องหมายว่าสามารถกำหนดค่าได้


43
คุณสมบัติถูกกำหนดให้ยังไม่ได้กำหนดยังเป็นคุณสมบัติของวัตถุดังนั้นมันจะไม่ถูกลบโดย GC เว้นแต่จะอ่านผิดย่อหน้าสุดท้ายของคุณ
Lance

8
ฉันผิดที่สัมผัสธีมของ GC ที่นี่ ทั้งสองวิธีมีผลลัพธ์เหมือนกันสำหรับ GC: พวกเขาลบค่าที่เชื่อมโยงกับคีย์ หากค่านั้นเป็นการอ้างอิงครั้งสุดท้ายกับวัตถุอื่น ๆ วัตถุนั้นจะถูกล้างข้อมูล
Dan

15
คุณสมบัติถูกกำหนดให้ยังไม่ได้กำหนดยังเป็นคุณสมบัติของวัตถุดังนั้นจะไม่ถูกลบโดย GC GC ไม่ได้จัดการอะไรเกี่ยวกับคุณสมบัติ มันรวบรวมและลบค่า ตราบใดที่ไม่มีการอ้างอิงถึงค่า (วัตถุ, สตริง, ฯลฯ ) อีกต่อไป GC จะลบมันออกจากหน่วยความจำ
คดเคี้ยว

8
BTW นั่นคือปัญหาที่สองในการตรวจสอบว่าคุณสมบัติที่มีอยู่บนวัตถุ Javascript ใช้ในการประกอบการเป็นที่น่าเชื่อถือ แต่ช้า ตรวจสอบว่าคุณสมบัติไม่ได้ถูกกำหนด "ไม่ใช่คำตอบที่ถูกต้อง" แต่มันเร็วกว่านี้ไหม ตรวจสอบ
rdllopes

8
คำตอบนี้ยังเกี่ยวข้องหรือไม่ ขณะนี้ jsperf ไม่ทำงาน แต่เกณฑ์มาตรฐานนี้ดูเหมือนว่าบ่งชี้ว่าความแตกต่างของความเร็วเป็นเพียง 25% ซึ่งใกล้เคียงกับ"~ 100 ครั้งช้าลง"ในคำตอบนี้
Cerbrus

248

var myObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
    
delete myObject.regex;

console.log ( myObject.regex); // logs: undefined

สิ่งนี้ใช้ได้ใน Firefox และ Internet Explorer และฉันคิดว่ามันใช้ได้กับทุกคน


216

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]

รายละเอียด

deleteใน JavaScript มีฟังก์ชั่นที่แตกต่างจากคำหลักใน C และ C ++: มันไม่ได้เพิ่มหน่วยความจำโดยตรง แต่มีวัตถุประสงค์เพียงอย่างเดียวคือการลบคุณสมบัติออกจากวัตถุ

สำหรับอาร์เรย์การลบคุณสมบัติที่สอดคล้องกับดัชนีจะสร้างอาร์เรย์แบบกระจาย (เช่นอาร์เรย์ที่มี "หลุม" อยู่ในนั้น) เบราว์เซอร์ส่วนใหญ่แสดงดัชนีอาร์เรย์ที่หายไปว่า "ว่างเปล่า"

var array = [0, 1, 2, 3]
delete array[2] // [0, 1, empty, 3]

โปรดทราบว่าdeleteไม่ได้ย้ายเข้ามาarray[3]array[2]

ฟังก์ชั่นในตัวที่แตกต่างกันใน JavaScript จัดการกับอาร์เรย์เบาบางแตกต่างกัน

  • for...in จะข้ามดัชนีว่างเปล่าอย่างสมบูรณ์

  • การforวนซ้ำแบบดั้งเดิมจะส่งคืนundefinedค่าที่ดัชนี

  • วิธีการใด ๆ ที่ใช้Symbol.iteratorจะส่งคืนundefinedค่าที่ดัชนี

  • forEach, mapและreduceก็จะข้ามดัชนีที่ขาดหายไป

ดังนั้นdeleteผู้ประกอบการไม่ควรใช้สำหรับกรณีการใช้งานทั่วไปของการลบองค์ประกอบจากอาร์เรย์ อาร์เรย์มีวิธีการเฉพาะสำหรับการลบองค์ประกอบและจัดสรรหน่วยความจำ: และArray#splice()Array#pop

Array # splice (เริ่ม [, 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.prototypeArray#slice

Array # slice ([start [, end]])

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]

อาร์เรย์ # ป๊อป

Array#popเอาองค์ประกอบสุดท้ายออกจากอาร์เรย์และส่งกลับองค์ประกอบนั้น การดำเนินการนี้จะเปลี่ยนความยาวของอาร์เรย์


12
วิธีการนี้จะไม่แก้ไขวัตถุต้นฉบับซึ่งอาจยังคงอ้างอิงอยู่ที่อื่น สิ่งนี้อาจจะใช่หรือไม่ใช่ปัญหาขึ้นอยู่กับการใช้งาน แต่เป็นสิ่งที่ต้องคำนึงถึง
Tamas Czinege

19
@ B1KMusic นี่คือวิธีการลบองค์ประกอบออกจาก Array: splice
wulftone

3
@wulftone nope ที่แยกอาร์เรย์และไม่ทำอะไรเลยเพื่อลบค่า ฉันคิดว่าวิธีที่ดีที่สุดในการลบจากอาเรย์ที่มีค่าเฉพาะที่จำเป็นในการลบคือการใช้deleteและสร้างฟังก์ชั่น Garbage Collection เพื่อล้างมัน
Braden ที่ดีที่สุด

5
ฉันไม่เห็นspliceในการแก้ไขของคุณ แต่removeควรเป็นArray.prototype.remove = function(index) { this.splice(index, 1); };
Ry-

1
บทความนี้เต็มไปด้วย bull 1 ไม่ตอบคำถาม! 2. มันเป็นตัวอย่างของการใช้ภาษาในทางที่ผิดและการบ่นว่า "มันใช้งานไม่ได้!" 3. อย่ากล่าวโทษโอเปอเรเตอร์การลบ JavaScript สำหรับข้อผิดพลาดที่เป็นนิสัยของ Crockford ที่ใส่nullสำหรับดัชนีอาร์เรย์ที่ว่างเปล่า เขาไม่เข้าใจความหมายของโมฆะ - เขาคิดว่ามันผิด ข้อผิดพลาดเป็นของเขาและคนเดียว - ไม่มีค่าลบในดัชนีอาร์เรย์ที่กำหนด ไม่มี "รู" ในอาเรย์นั่นคือดัชนีที่ว่างเปล่า ถูกต้องตามกฎหมายและคาดหวังอย่างแน่นอน
Bekim Bacaj

195

คำถามเก่า ๆ คำตอบที่ทันสมัย การใช้การทำลายวัตถุคุณลักษณะ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);

คุณสามารถดูได้ในเครื่องมือแก้ไขแบบทดลองของ Babel


แก้ไข:

หากต้องการมอบหมายตัวแปรเดียวกันให้ใช้let:

let myObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
({ regex, ...myObject } = myObject);
console.log(myObject);

6
อาจเป็นเพราะเป้าหมายคือการลบคุณสมบัติออกจากวัตถุไม่ใช่สร้างใหม่โดยไม่มีคุณสมบัติ ... แม้ว่าวิธีการแก้ปัญหาของคุณจะเป็นที่ชื่นชอบเนื่องจากฉันชอบวิธีที่ไม่เปลี่ยนรูป
Vingt_centimes

8
คำถามระบุว่า "เพื่อจบด้วยmyObject ใหม่ "
โคเอ็น

1
การเพิ่มขีดถอดทรัพย์สินจะครอกโครงการของคุณ :) แทนที่จะมีมันใช้ได้ในฐานะที่regexคุณยังสามารถกำหนดให้กับตัวแปรอื่น ๆ เช่นสิ่งที่ถูกนำมาใช้ในภาษาเช่นไปทิ้งผล:_ const { regex: _, ...newObject } = myObject;
โคเอ็น

2
@PranayKumar ฉันหวังว่าไวยากรณ์นี้จะใช้งานได้ const { [key], ...newObject } = myObject;แต่มันก็ไม่ได้ดังนั้นฉันจึงไม่คิดว่ามันจะเป็นไปได้ด้วยการทำลายล้าง
โคเอ็น

2
ด้วยfreeze()'D และseal()' d วัตถุคุณไม่สามารถเพียงแค่deleteสถานที่ให้บริการ ดังนั้นนี่คือทางเลือกที่ยอดเยี่ยม แม้ว่าในกรณีส่วนใหญ่อาจไม่เหมาะสมที่จะลบคุณสมบัติออกจากวัตถุที่ถูกแช่แข็ง / ปิดผนึกอย่างไรก็ตามการพิจารณาว่าจุดทั้งหมดคือการรับประกันบางอย่างเกี่ยวกับโครงสร้างข้อมูลของคุณซึ่งรูปแบบนี้จะบ่อนทำลาย สำหรับกรณีที่คุณต้องการดักวัตถุโดยไม่ทำลาย แต่ไม่มีคุณสมบัติบางอย่างมันสมบูรณ์แบบ
Braden Best

118

สเปรดไวยากรณ์ (ES6)

สำหรับผู้ที่ต้องการมัน ...

หากต้องการคำตอบ @Koen ในกระทู้นี้ให้สมบูรณ์ในกรณีที่คุณต้องการลบตัวแปรแบบไดนามิกโดยใช้ไวยากรณ์การแพร่กระจายคุณสามารถทำได้ดังนี้:

const key = 'a';
        
const { [key]: foo, ...rest } = { a: 1, b: 2, c: 3 };

console.log(foo);  // 1
console.log(rest); // { b: 2, c: 3 }

* fooจะเป็นตัวแปรใหม่ที่มีค่าa(ซึ่งก็คือ 1)


คำตอบที่ขยายออกไป 😇
มีวิธีทั่วไปสองสามวิธีในการลบคุณสมบัติออกจากวัตถุ
แต่ละคนมีข้อดีและข้อเสียของตัวเอง (ตรวจสอบการเปรียบเทียบประสิทธิภาพ ):

Delete Operator สามารถ
อ่านได้และย่ออย่างไรก็ตามมันอาจไม่ใช่ตัวเลือกที่ดีที่สุดหากคุณใช้งานกับวัตถุจำนวนมากเนื่องจากประสิทธิภาพของมันไม่ได้รับการปรับให้เหมาะสม

delete obj[key];


การโอนสิทธิ
มากกว่า 2 เท่าเร็วกว่าdeleteอย่างไรก็ตามคุณสมบัติจะไม่ถูกลบและสามารถทำซ้ำได้

obj[key] = null;
obj[key] = false;
obj[key] = undefined;


ผู้ประกอบการแพร่กระจายตัวดำเนินการ
นี้ES6ช่วยให้เราสามารถส่งคืนวัตถุใหม่เอี่ยมยกเว้นคุณสมบัติใด ๆ โดยไม่ต้องกลายพันธุ์วัตถุที่มีอยู่ ข้อเสียคือมันมีประสิทธิภาพที่แย่กว่าข้างต้นและไม่แนะนำให้ใช้เมื่อคุณต้องการลบคุณสมบัติหลาย ๆ อย่างในเวลาเดียวกัน

{ [key]: val, ...rest } = obj;

2
ฉันคิดว่าไวยากรณ์การแพร่กระจาย / ส่วนที่เหลือสำหรับตัวอักษรวัตถุรวมอยู่ใน ES2018 (ES9) ไม่ใช่ ES6 แม้ว่าเครื่องมือ JS หลายตัวได้นำไปใช้แล้ว
trincot

2
@trincot เปิดตัวครั้งแรกในปี 2014 ( github.com/tc39/proposal-object-rest-spread ) และเป็นคุณลักษณะ ES6 (ECMAScript 2015 aka ECMAScript 6th Edition) อย่างไรก็ตามแม้ว่าฉันผิดฉันไม่คิดว่ามันจะสร้างความแตกต่างให้กับบริบทของคำตอบ
Lior Elrom

2
ลิงก์อ้างอิงถึง ES6 โดยที่จริงแล้วมีการแนะนำให้ใช้ไวยากรณ์การแพร่กระจายของอาร์เรย์ แต่ก็ยังคงเสนอสิ่งที่คล้ายกันสำหรับตัวอักษรวัตถุ ส่วนที่สองนั้นรวมอยู่ใน ES9 เท่านั้นหากฉันไม่เข้าใจผิด
trincot

98

อีกทางเลือกหนึ่งคือการใช้ไลบรารีUnderscore.js

โปรดทราบว่า_.pick()และ_.omit()ทั้งสองส่งคืนสำเนาของวัตถุและไม่แก้ไขวัตถุต้นฉบับโดยตรง การกำหนดผลลัพธ์ให้กับวัตถุดั้งเดิมควรทำการหลอกลวง (ไม่แสดง)

การอ้างอิง: ลิงค์ _.pick (วัตถุ, ปุ่ม *)

ส่งคืนสำเนาของวัตถุกรองเพื่อให้มีค่าสำหรับคีย์ที่อนุญาตพิเศษเท่านั้น (หรืออาร์เรย์ของคีย์ที่ใช้ได้)

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

_.pick(myJSONObject, "ircEvent", "method");
=> {"ircEvent": "PRIVMSG", "method": "newURI"};

การอ้างอิง: ลิงค์ _.omit (วัตถุ, ปุ่ม *)

ส่งคืนสำเนาของวัตถุถูกกรองเพื่อละเว้นคีย์บัญชีดำ (หรืออาร์เรย์ของคีย์)

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

_.omit(myJSONObject, "regex");
=> {"ircEvent": "PRIVMSG", "method": "newURI"};

สำหรับอาร์เรย์_.filter()และ_.reject()สามารถใช้ในลักษณะที่คล้ายกัน


4
โปรดทราบว่าหากคีย์ของวัตถุของคุณเป็นตัวเลขคุณอาจต้อง_.omit(collection, key.toString())
Jordan Arseno

Hmmmmm .... เครื่องหมายขีดล่างdelete obj[prop]ช้ากว่า ~ 100x มากกว่า ~ 100x ช้ากว่า obj[prop] = undefined
Jack Giffin

52

คำที่คุณใช้ในชื่อคำถามของคุณRemove a property from a JavaScript objectสามารถตีความได้หลายวิธี หนึ่งคือการลบมันสำหรับหน่วยความจำทั้งหมดและรายชื่อของคีย์วัตถุหรืออื่น ๆ เพียงเพื่อลบออกจากวัตถุของคุณ ตามที่ได้รับการกล่าวถึงในคำตอบอื่น ๆ คำdeleteหลักคือส่วนหลัก สมมติว่าคุณมีวัตถุของคุณเช่น:

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

ถ้าคุณทำ:

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

ผลลัพธ์จะเป็น:

["ircEvent", "method", "regex"]

คุณสามารถลบคีย์เฉพาะจากคีย์อ็อบเจ็กต์ของคุณเช่น:

delete myJSONObject["regex"];

ดังนั้นการใช้คีย์วัตถุของคุณObject.keys(myJSONObject)จะเป็น:

["ircEvent", "method"]

แต่ประเด็นคือถ้าคุณใส่ใจเกี่ยวกับหน่วยความจำและคุณต้องการให้วัตถุทั้งหมดถูกลบออกจากหน่วยความจำเราขอแนะนำให้ตั้งเป็นโมฆะก่อนที่คุณจะลบกุญแจ:

myJSONObject["regex"] = null;
delete myJSONObject["regex"];

จุดสำคัญอื่น ๆ ที่นี่คือต้องระมัดระวังเกี่ยวกับการอ้างอิงอื่น ๆ ของคุณไปยังวัตถุเดียวกัน ตัวอย่างเช่นหากคุณสร้างตัวแปรเช่น:

var regex = myJSONObject["regex"];

หรือเพิ่มเป็นตัวชี้ใหม่ไปยังวัตถุอื่นเช่น:

var myOtherObject = {};
myOtherObject["regex"] = myJSONObject["regex"];

แม้ว่าคุณจะลบมันออกจากวัตถุของคุณวัตถุmyJSONObjectนั้นจะไม่ถูกลบออกจากหน่วยความจำเนื่องจากregexตัวแปรและmyOtherObject["regex"]ยังคงมีค่าอยู่ ถ้าอย่างนั้นเราจะเอาวัตถุออกจากหน่วยความจำได้อย่างไร?

คำตอบคือการลบการอ้างอิงทั้งหมดที่คุณมีในรหัสของคุณชี้ไปที่วัตถุนั้นมากและยังไม่ได้ใช้varคำสั่งเพื่อสร้างการอ้างอิงใหม่ไปยังวัตถุนั้น จุดสุดท้ายนี้เกี่ยวกับvarข้อความเป็นหนึ่งในประเด็นที่สำคัญที่สุดที่เรามักเผชิญอยู่เนื่องจากการใช้varข้อความจะป้องกันไม่ให้วัตถุที่สร้างขึ้นถูกลบออก

ซึ่งหมายความว่าในกรณีนี้คุณจะไม่สามารถลบวัตถุนั้นได้เนื่องจากคุณได้สร้างregexตัวแปรผ่านvarคำสั่งและหากคุณ:

delete regex; //False

ผลลัพธ์จะเป็นfalseซึ่งหมายความว่าคำสั่งลบของคุณยังไม่ได้ดำเนินการตามที่คาดไว้ แต่ถ้าคุณไม่ได้สร้างตัวแปรนั้นมาก่อนและคุณมีเพียงแค่myOtherObject["regex"]การอ้างอิงที่มีอยู่ล่าสุดคุณสามารถทำได้โดยลบมันเช่น:

myOtherObject["regex"] = null;
delete myOtherObject["regex"];

กล่าวอีกนัยหนึ่งวัตถุ JavaScript จะถูกฆ่าทันทีที่ไม่มีการอ้างอิงเหลืออยู่ในรหัสของคุณซึ่งชี้ไปที่วัตถุนั้น


อัปเดต: ขอบคุณ @AgentME:

การตั้งค่าคุณสมบัติเป็นโมฆะก่อนที่จะลบมันจะไม่ทำสิ่งใดให้สำเร็จ (เว้นแต่ว่าวัตถุนั้นถูกผนึกโดย Object.seal และการลบล้มเหลวซึ่งโดยปกติจะไม่ใช่กรณีเว้นแต่คุณจะพยายามเป็นพิเศษ)

วิธีรับข้อมูลเพิ่มเติมเกี่ยวกับObject.seal: Object.seal ()


คุณผิด - มีเพียงวัตถุเท่านั้นที่ถูกส่งผ่านโดยการอ้างอิงใน JavaScript ดังนั้นหากmyJSONObject.regexค่าของมันคือสตริงและคุณกำหนดให้วัตถุอื่นวัตถุอื่น ๆ จะมีสำเนาของค่านี้
MichałPerłakowski

คุณพูดถูกและนี่เป็นข้อความอ้างอิง: "ให้ระวังการอ้างอิงอื่น ๆ ของคุณไปยังวัตถุเดียวกัน"
Mehran Hatami

43

ECMAScript 2015 (หรือ ES6) มาพร้อมกับวัตถุReflectในตัว เป็นไปได้ที่จะลบคุณสมบัติของวัตถุโดยเรียกฟังก์ชัน Reflect.deleteProperty ()พร้อมกับวัตถุเป้าหมายและรหัสคุณสมบัติเป็นพารามิเตอร์:

Reflect.deleteProperty(myJSONObject, 'regex');

ซึ่งเทียบเท่ากับ:

delete myJSONObject['regex'];

แต่ถ้าคุณสมบัติของวัตถุนั้นไม่สามารถกำหนดค่าได้จะไม่สามารถลบได้ด้วยฟังก์ชั่น deleteProperty หรือตัวดำเนินการลบ:

let obj = Object.freeze({ prop: "value" });
let success = Reflect.deleteProperty(obj, "prop");
console.log(success); // false
console.log(obj.prop); // value

Object.freeze ()ทำให้คุณสมบัติทั้งหมดของวัตถุไม่สามารถกำหนดค่าได้ (นอกเหนือจากสิ่งอื่น ๆ ) deletePropertyฟังก์ชั่น (เช่นเดียวกับผู้ประกอบการลบ ) ผลตอบแทน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

1
@Gothdo มันมีประโยชน์มากขึ้นโดยเฉพาะเมื่อคุณต้องการทำบางสิ่งที่ใช้งานได้ เช่นคุณสามารถกำหนดฟังก์ชั่นให้กับตัวแปรผ่านเป็นอาร์กิวเมนต์หรือการใช้งานapply, call, bindฟังก์ชั่น ...
madox2

41

สมมติว่าคุณมีวัตถุที่มีลักษณะเช่นนี้:

var Hogwarts = {
    staff : [
        'Argus Filch',
        'Filius Flitwick',
        'Gilderoy Lockhart',
        'Minerva McGonagall',
        'Poppy Pomfrey',
        ...
    ],
    students : [
        'Hannah Abbott',
        'Katie Bell',
        'Susan Bones',
        'Terry Boot',
        'Lavender Brown',
        ...
    ]
};

การลบคุณสมบัติวัตถุ

หากคุณต้องการใช้ทั้งstaffอาร์เรย์วิธีที่เหมาะสมในการทำเช่นนี้คือ:

delete Hogwarts.staff;

หรือคุณสามารถทำสิ่งนี้:

delete Hogwarts['staff'];

ในทำนองเดียวกันการเอานักเรียนทั้งอาร์เรย์จะทำได้โดยการโทรหรือdelete Hogwarts.students;delete Hogwarts['students'];

การลบดัชนีอาร์เรย์

ตอนนี้ถ้าคุณต้องการที่จะลบพนักงานหรือนักเรียนคนเดียวขั้นตอนจะแตกต่างกันเล็กน้อยเพราะทั้งสองคุณสมบัติเป็นอาร์เรย์ตัวเอง

หากคุณรู้จักดัชนีของพนักงานคุณสามารถทำสิ่งนี้ได้:

Hogwarts.staff.splice(3, 1);

หากคุณไม่รู้จักดัชนีคุณจะต้องค้นหาดัชนีด้วย:

Hogwarts.staff.splice(Hogwarts.staff.indexOf('Minerva McGonnagall') - 1, 1);

บันทึก

ในขณะที่คุณสามารถใช้deleteอาเรย์กับเทคนิคการใช้มันจะส่งผลให้ได้ผลลัพธ์ที่ไม่ถูกต้องเมื่อมีการเรียกตัวอย่างในHogwarts.staff.lengthภายหลัง กล่าวอีกนัยหนึ่งคือdeleteจะลบองค์ประกอบ แต่จะไม่อัปเดตมูลค่าของlengthทรัพย์สิน การใช้deleteจะทำให้การจัดทำดัชนีของคุณยุ่งเหยิง

ดังนั้นเมื่อลบค่าออกจากวัตถุก่อนอื่นให้พิจารณาว่าคุณกำลังจัดการกับคุณสมบัติของวัตถุหรือไม่ว่าคุณกำลังจัดการกับค่าอาร์เรย์และเลือกกลยุทธ์ที่เหมาะสมตามนั้น

หากคุณต้องการทดลองสิ่งนี้คุณสามารถใช้ซอนี้เป็นจุดเริ่มต้น


ฉันจะคิดว่าคุณควรใช้ในอาร์เรย์แทนsplice delete
Joel Trauger

@ JoelTrauger: นั่นคือสิ่งที่ฉันกำลังพูด ;-)
จอห์น Slegers

ใช่. ความคิดเห็นของฉันคือสิ่งนั้นdeleteไม่ควรเป็นอย่างนั้น มันspliceคือสิ่งที่ OP มองหา
Joel Trauger

1
@ JoelTrauger: ฉันพยายามอธิบายdeleteควรใช้คุณสมบัติของวัตถุและspliceองค์ประกอบของอาร์เรย์
John Slegers

ประกบกันช้ามาก ในขณะที่ควรใช้แทนdeleteในอาร์เรย์มันจะเป็นการดีที่จะไม่สร้างรหัสที่อยู่กึ่งกลางเลย
Jack Giffin

39

ใช้ ES6:

(การทำลายโครงสร้าง + ตัวดำเนินการกระจาย)

const myObject = {
    regex: "^http://.*",
    b: 2,
    c: 3
};
const { regex, ...noRegex } = myObject;
console.log(noRegex); // => { b: 2, c: 3 }

ฉันไม่คิดว่านี่เป็นคุณสมบัติ ES6 แต่เป็นคุณลักษณะที่รวมอยู่ใน ES9 เท่านั้น
trincot

ดังนั้นจริง ๆ แล้วคุณไม่ได้ใช้ ES6 ตามที่คุณเขียน แต่ ES9 ... ;-)
trincot

2
สิ่งนี้ไม่ได้เป็นการเอาคุณสมบัติออกจากวัตถุ แต่เป็นการสร้างวัตถุใหม่โดยไม่มีคุณสมบัตินั้น
Jordi Nebot


31

ตัวดำเนินการลบเป็นวิธีที่ดีที่สุด

ตัวอย่างสดที่จะแสดง:

var foo = {bar: 'bar'};
delete foo.bar;
console.log('bar' in foo); // Logs false, because bar was deleted from foo.

อาจเป็นเรื่องที่น่าสังเกตว่าแม้ว่าการใช้ตัวdeleteดำเนินการจะดีต่อสุขภาพในเรื่องของการเก็บขยะแต่ก็อาจช้าอย่างไม่คาดคิดในส่วนเล็ก ๆ ด้วยเหตุผลเดียวกัน
John Weisz

29

ในการโคลนวัตถุโดยไม่มีคุณสมบัติ:

ตัวอย่างเช่น:

let object = { a: 1, b: 2, c: 3 };   

และเราจำเป็นต้องลบ 'a'

1. ด้วยคีย์ prop ชัดเจน:

const { a, ...rest } = object;
object = rest;

2. กับตัวแปรที่สำคัญ prop:

const propKey = 'a';
const { [propKey]: propValue, ...rest } = object;
object = rest;

3. ฟังก์ชั่นลูกศรเย็น😎:

const removePropery = (propKey, { [propKey]: propValue, ...rest }) => rest;

object = removePropery('a', object);

4. สำหรับคุณสมบัติหลาย ๆ

const removeProperties = (object, ...keys) => Object.entries(object).reduce((prev, [key, value]) => ({...prev, ...(!keys.includes(key) && { [key]: value }) }), {})

การใช้

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

หรือ

    const propsToRemove = ['a', 'b']
    object = removeProperties(object, ...propsToRemove) // result => { c: 3 }

1
ฟังก์ชันลูกศรเนียน!
JSilv

27

การใช้วิธีการลบเป็นวิธีที่ดีที่สุดในการทำตามคำอธิบาย MDN ตัวดำเนินการลบจะลบคุณสมบัติออกจากวัตถุ ดังนั้นคุณสามารถเขียน:

delete myObject.regex;
// OR
delete myObject['regex'];

ตัวดำเนินการลบจะลบคุณสมบัติที่กำหนดออกจากวัตถุ เมื่อลบสำเร็จจะส่งคืนจริงและจะส่งคืนค่าเท็จ อย่างไรก็ตามมันเป็นสิ่งสำคัญที่จะต้องพิจารณาสถานการณ์สมมติต่อไปนี้:

  • หากคุณสมบัติที่คุณพยายามลบไม่มีอยู่การลบจะไม่มีผลใด ๆ และจะคืนค่าจริง

  • หากมีคุณสมบัติที่มีชื่อเดียวกันอยู่บนโซ่ต้นแบบของวัตถุหลังจากลบแล้ววัตถุจะใช้คุณสมบัติจากโซ่ต้นแบบ (กล่าวอีกนัยหนึ่งคือการลบจะมีผลกับคุณสมบัติของตัวเองเท่านั้น)

  • คุณสมบัติใด ๆ ที่ประกาศด้วย var ไม่สามารถลบได้จากขอบเขตส่วนกลางหรือจากขอบเขตของฟังก์ชัน

  • ดังนั้นการลบไม่สามารถลบฟังก์ชั่นใด ๆ ในขอบเขตส่วนกลาง (ไม่ว่าจะเป็นส่วนหนึ่งของการกำหนดฟังก์ชั่นหรือฟังก์ชั่น (การแสดงออก)

  • ฟังก์ชันที่เป็นส่วนหนึ่งของวัตถุ (นอกเหนือจาก
    ขอบเขตส่วนกลาง) สามารถลบได้ด้วยการลบ

  • คุณสมบัติใด ๆ ที่ประกาศพร้อมกับอนุญาตหรือ const ไม่สามารถลบออกจากขอบเขตที่กำหนดไว้ได้ ไม่สามารถลบคุณสมบัติที่ไม่สามารถกำหนดค่าได้ ซึ่งรวมถึงคุณสมบัติของวัตถุในตัวเช่น Math, Array, Object และคุณสมบัติที่สร้างขึ้นโดยไม่สามารถกำหนดค่าได้ด้วยวิธีการเช่น Object.defineProperty ()

ตัวอย่างต่อไปนี้ให้อีกตัวอย่างง่ายๆ:

var Employee = {
      age: 28,
      name: 'Alireza',
      designation: 'developer'
    }
    
    console.log(delete Employee.name);   // returns true
    console.log(delete Employee.age);    // returns true
    
    // When trying to delete a property that does 
    // not exist, true is returned 
    console.log(delete Employee.salary); // returns true

สำหรับข้อมูลเพิ่มเติมเกี่ยวกับและดูตัวอย่างเพิ่มเติมโปรดไปที่ลิงค์ด้านล่าง:

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


22

Array#reduceทางออกก็ใช้

var myObject = {
  "ircEvent": "PRIVMSG",
  "method": "newURI",
  "regex": "^http://.*"
};

myObject = Object.keys(myObject).reduce(function(obj, key) {
  if (key != "regex") {           //key you want to remove
    obj[key] = myObject[key];
  }
  return obj;
}, {});

console.log(myObject);

อย่างไรก็ตามมันจะกลายพันธุ์วัตถุต้นฉบับ หากคุณต้องการสร้างวัตถุใหม่โดยไม่มีคีย์ที่ระบุให้กำหนดฟังก์ชันลดให้กับตัวแปรใหม่เช่น:

(ES6)

const myObject = {
  ircEvent: 'PRIVMSG',
  method: 'newURI',
  regex: '^http://.*',
};

const myNewObject = Object.keys(myObject).reduce((obj, key) => {
  key !== 'regex' ? obj[key] = myObject[key] : null;
  return obj;
}, {});

console.log(myNewObject);


21

โพสต์นี้เก่ามากและฉันคิดว่ามันมีประโยชน์มากดังนั้นฉันจึงตัดสินใจที่จะแบ่งปันฟังก์ชั่น unset ที่ฉันเขียนไว้ในกรณีที่มีคนอื่นเห็นโพสต์นี้และคิดว่าทำไมมันไม่ง่ายอย่างนั้นใน PHP unset

เหตุผลในการเขียนunsetฟังก์ชั่นใหม่นี้คือการเก็บดัชนีของตัวแปรอื่น ๆ ทั้งหมดใน hash_map นี้ ดูตัวอย่างต่อไปนี้และดูว่าดัชนีของ "test2" ไม่เปลี่ยนแปลงหลังจากลบค่าออกจาก hash_map

function unset(unsetKey, unsetArr, resort){
  var tempArr = unsetArr;
  var unsetArr = {};
  delete tempArr[unsetKey];
  if(resort){
    j = -1;
  }
  for(i in tempArr){
    if(typeof(tempArr[i]) !== 'undefined'){
      if(resort){
        j++;
      }else{
        j = i;
      }
      unsetArr[j] = tempArr[i];
    }
  }
  return unsetArr;
}

var unsetArr = ['test','deletedString','test2'];

console.log(unset('1',unsetArr,true)); // output Object {0: "test", 1: "test2"}
console.log(unset('1',unsetArr,false)); // output Object {0: "test", 2: "test2"}

20

มีคำตอบที่ดีมากมายที่นี่ แต่ฉันต้องการที่จะพูดสอดเมื่อใช้การลบเพื่อลบคุณสมบัติใน JavaScript มันมักจะฉลาดตรวจสอบก่อนว่าคุณสมบัติที่มีอยู่เพื่อป้องกันข้อผิดพลาด

เช่น

var obj = {"property":"value", "property2":"value"};

if (obj && obj.hasOwnProperty("property2")) {
  delete obj.property2;
} else {
  //error handling
}

เนื่องจากลักษณะแบบไดนามิกของ JavaScript มักจะมีกรณีที่คุณไม่ทราบว่ามีคุณสมบัติหรือไม่ การตรวจสอบว่ามี obj อยู่ก่อนหน้า && และอย่าลืมข้อผิดพลาดเนื่องจากการเรียกใช้ฟังก์ชัน hasOwnProperty () บนวัตถุที่ไม่ได้กำหนด

ขออภัยหากนี่ไม่ได้เพิ่มในกรณีการใช้งานเฉพาะของคุณ แต่ฉันเชื่อว่านี่เป็นการออกแบบที่ดีที่จะปรับเมื่อจัดการวัตถุและคุณสมบัติของพวกเขา


2
ลบ foo.bar ทำงานแม้ว่าจะไม่มีแถบดังนั้นการทดสอบของคุณค่อนข้างมาก IMHO
PhiLho

@PhiLho ที่ขึ้นอยู่กับว่าคุณกำลังใช้จาวาสคริปต์อยู่ที่ไหน ใน Node.js ฉันเชื่อว่านี่เป็นสาเหตุให้เซิร์ฟเวอร์ของคุณเกิดขัดข้อง
วิลเล็ม

2
delete foo.bar;เพียงโยนข้อยกเว้นถ้า foo เป็นเท็จหรือถ้าคุณอยู่ในโหมดเข้มงวดและ foo เป็นวัตถุที่มีคุณสมบัติแถบที่ไม่สามารถกำหนดค่าได้
Macil

ฉันไม่จำปัญหาที่แน่นอนที่ฉันเคยมีในเรื่องนี้ แต่ฉันคิดว่าปัญหาอาจปรากฏขึ้นเมื่อตัวเองไม่อยู่และคุณพยายามที่จะลบมัน
วิลเล็ม

ใช่คุณต้องทดสอบว่ามี foo อยู่หรือไม่มิเช่นนั้น foo.bar จะเป็นข้อยกเว้น แต่คุณไม่จำเป็นต้องตรวจสอบสถานะของแถบก่อนที่จะลบออก นั่นเป็นส่วนที่ "มากเกินไป" ในความคิดเห็นของฉัน :-)
PhiLho

16

การใช้ramda # dissocคุณจะได้รับวัตถุใหม่โดยไม่มีแอตทริบิวต์regex:

const newObject = R.dissoc('regex', myObject);
// newObject !== myObject

นอกจากนี้คุณยังสามารถใช้ฟังก์ชั่นอื่น ๆ เพื่อให้ได้เอฟเฟกต์เดียวกัน - ละเว้น, เลือก, ...


15

ลองวิธีต่อไปนี้ กำหนดค่าคุณสมบัติการObject undefinedจากนั้นวัตถุและstringifyparse

 var myObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};

myObject.regex = undefined;
myObject = JSON.parse(JSON.stringify(myObject));

console.log(myObject);


1
ยังJSON.parse(JSON.stringify({ ...myObject, regex: undefined }))
noisypixy

12

หากคุณต้องการที่จะลบคุณสมบัติที่ซ้อนกันอย่างลึกล้ำในวัตถุคุณสามารถใช้ฟังก์ชั่นวนซ้ำต่อไปนี้ด้วยพา ธ ไปยังคุณสมบัติเป็นอาร์กิวเมนต์ที่สอง:

var deepObjectRemove = function(obj, path_to_key){
    if(path_to_key.length === 1){
        delete obj[path_to_key[0]];
        return true;
    }else{
        if(obj[path_to_key[0]])
            return deepObjectRemove(obj[path_to_key[0]], path_to_key.slice(1));
        else
            return false;
    }
};

ตัวอย่าง:

var a = {
    level1:{
        level2:{
            level3: {
                level4: "yolo"
            }
        }
    }
};

deepObjectRemove(a, ["level1", "level2", "level3"]);
console.log(a);

//Prints {level1: {level2: {}}}

ฟังก์ชั่นนี้ใช้งานได้อย่างมีเสน่ห์ แต่ทำไมเราต้องกลับจริงและกลับเท็จ? รุ่นของฉันของรหัส: codepen.io/anon/pen/rwbppY รุ่นของฉันจะล้มเหลวไม่ว่ากรณีใด ๆ ?
ปกติ

@ witty2017 มันจะไม่ล้มเหลว สถานที่ที่ฉันใช้ฟังก์ชั่นนั้นยังจำเป็นเพื่อตรวจสอบว่ามีคุณสมบัติอยู่แล้วหรือไม่ ถ้าไม่มีคุณสมบัติก็จะคืนค่าเป็นเท็จ หากพบสถานที่ให้บริการและลบมันก็จะกลับมาจริง
ayushgp

8

คุณสามารถลบคุณสมบัติใด ๆ ของวัตถุโดยใช้deleteคำสำคัญ

ตัวอย่างเช่น:

var obj = {key1:"val1",key2:"val2",key3:"val3"}

หากต้องการลบคุณสมบัติใด ๆ ให้key1ใช้deleteคำหลักดังนี้:

delete obj.key1

หรือคุณสามารถใช้สัญลักษณ์คล้ายอาร์เรย์:

delete obj[key1]

Ref: MDN


8

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

const obj = {
    "Filters":[
        {
            "FilterType":"between",
            "Field":"BasicInformationRow.A0",
            "MaxValue":"2017-10-01",
            "MinValue":"2017-09-01",
            "Value":"Filters value"
        }
    ]
};

let new_obj1 = Object.assign({}, obj.Filters[0]);
let new_obj2 = Object.assign({}, obj.Filters[0]);

/*

// old version

let shaped_obj1 = Object.keys(new_obj1).map(
    (key, index) => {
        switch (key) {
            case "MaxValue":
                delete new_obj1["MaxValue"];
                break;
            case "MinValue":
                delete new_obj1["MinValue"];
                break;
        }
        return new_obj1;
    }
)[0];


let shaped_obj2 = Object.keys(new_obj2).map(
    (key, index) => {
        if(key === "Value"){
            delete new_obj2["Value"];
        }
        return new_obj2;
    }
)[0];


*/


// new version!

let shaped_obj1 = Object.keys(new_obj1).forEach(
    (key, index) => {
        switch (key) {
            case "MaxValue":
                delete new_obj1["MaxValue"];
                break;
            case "MinValue":
                delete new_obj1["MinValue"];
                break;
            default:
                break;
        }
    }
);

let shaped_obj2 = Object.keys(new_obj2).forEach(
    (key, index) => {
        if(key === "Value"){
            delete new_obj2["Value"];
        }
    }
);


7

การยืนยันของแดนว่า 'ลบ' ช้ามากและเป็นมาตรฐานที่เขาโพสต์สงสัย ดังนั้นฉันจึงทำการทดสอบด้วยตนเองใน Chrome 59 ดูเหมือนว่า 'ลบ' จะช้ากว่าประมาณ 30 เท่า:

var iterationsTotal = 10000000;  // 10 million
var o;
var t1 = Date.now(),t2;
for (let i=0; i<iterationsTotal; i++) {
   o = {a:1,b:2,c:3,d:4,e:5};
   delete o.a; delete o.b; delete o.c; delete o.d; delete o.e;
}
console.log ((t2=Date.now())-t1);  // 6135
for (let 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 = undefined;
}
console.log (Date.now()-t2);  // 205

โปรดทราบว่าฉันดำเนินการ 'ลบ' มากกว่าหนึ่งครั้งในหนึ่งวงรอบเพื่อลดผลกระทบที่เกิดจากการดำเนินการอื่น ๆ


7

พิจารณาสร้างวัตถุใหม่โดยไม่มี"regex"คุณสมบัติเนื่องจากวัตถุต้นฉบับสามารถอ้างอิงได้โดยส่วนอื่น ๆ ของโปรแกรมของคุณ ดังนั้นคุณควรหลีกเลี่ยงการจัดการมัน

const myObject = {
    "ircEvent": "PRIVMSG",
    "method": "newURI",
    "regex": "^http://.*"
};

const { regex, ...newMyObject } = myObject;

console.log(newMyObject);


SyntaxError: Unexpected token '...'. Expected a property name.?
Krzysztof Przygoda

ลองใช้เบราว์เซอร์สมัยใหม่เช่น Firefox, Chromium หรือ Safari และฉันคาดหวังว่ามันจะทำงานกับ Edge ได้เช่นกัน
ideaboxer

อีกทางเลือกหนึ่งหากลูกค้าของคุณบังคับให้คุณสนับสนุนเบราว์เซอร์ที่ล้าสมัยคุณสามารถลองใช้ TypeScript ซึ่ง transpiles รหัสของคุณเป็นไวยากรณ์แบบดั้งเดิม (+ ให้คุณประโยชน์ของความปลอดภัยประเภทคงที่)
ideaboxer

7

การลบคุณสมบัติใน JavaScript

มีตัวเลือกต่าง ๆ มากมายที่นำเสนอในหน้านี้ไม่ใช่เพราะตัวเลือกส่วนใหญ่ผิด - หรือเพราะคำตอบซ้ำกัน - แต่เนื่องจากเทคนิคที่เหมาะสมขึ้นอยู่กับสถานการณ์ที่คุณอยู่และเป้าหมายของงานที่คุณและ / หรือคุณ ทีมกำลังพยายามเติมเต็ม ในการตอบคำถามของคุณอย่างแจ่มแจ้งคุณจำเป็นต้องรู้:

  1. เวอร์ชันของ ECMAScript ที่คุณกำหนดเป้าหมาย
  2. ช่วงของประเภทวัตถุที่คุณต้องการลบคุณสมบัติและประเภทของชื่อคุณสมบัติที่คุณต้องสามารถตัดออกได้ (สตริงเท่านั้นสัญลักษณ์สัญลักษณ์ที่อ่อนแอการอ้างอิงที่แมปจากออบเจกต์เหล่านี้เป็นพอยน์เตอร์ประเภทคุณสมบัติทั้งหมดใน JavaScript เป็นเวลาหลายปีแล้ว )
  3. จริยธรรมการเขียนโปรแกรม / รูปแบบที่คุณและทีมของคุณใช้ คุณชอบแนวทางการทำงานและการกลายพันธุ์ที่มี verboten ในทีมของคุณหรือคุณใช้เทคนิคเชิงวัตถุกลายพันธุ์ตะวันตก?
  4. คุณกำลังมองหาเพื่อให้ได้สิ่งนี้ใน JavaScript ที่บริสุทธิ์หรือคุณเต็มใจและสามารถใช้ห้องสมุดบุคคลที่สามได้หรือไม่?

เมื่อตอบคำถามทั้งสี่ข้อแล้วจะมี "การลบคุณสมบัติ" สี่หมวดหมู่ใน JavaScript เพื่อเลือกจากเพื่อให้บรรลุเป้าหมายของคุณ พวกเขาคือ:

การลบคุณสมบัติวัตถุแบบรวมไม่ปลอดภัย

หมวดหมู่นี้ใช้สำหรับการดำเนินการกับวัตถุตัวอักษรหรืออินสแตนซ์ของวัตถุเมื่อคุณต้องการเก็บ / ดำเนินการต่อเพื่อใช้การอ้างอิงดั้งเดิมและไม่ได้ใช้หลักการทำงานที่ไร้สัญชาติในรหัสของคุณ ตัวอย่างส่วนของไวยากรณ์ในหมวดหมู่นี้:

'use strict'
const iLikeMutatingStuffDontI = { myNameIs: 'KIDDDDD!', [Symbol.for('amICool')]: true }
delete iLikeMutatingStuffDontI[Symbol.for('amICool')] // true
Object.defineProperty({ myNameIs: 'KIDDDDD!', 'amICool', { value: true, configurable: false })
delete iLikeMutatingStuffDontI['amICool'] // throws

หมวดหมู่นี้เป็นหมวดหมู่การกำจัดอสังหาริมทรัพย์ที่เก่าแก่ที่สุดตรงไปตรงมาที่สุดและได้รับการสนับสนุนอย่างกว้างขวางที่สุด สนับสนุนSymbol& ดัชนีอาร์เรย์นอกเหนือจากสตริงและใช้งานได้กับทุกเวอร์ชันของ JavaScript ยกเว้นรุ่นแรก อย่างไรก็ตามมันเป็นการเปลี่ยนแปลงซึ่งละเมิดหลักการเขียนโปรแกรมบางอย่างและมีผลกระทบต่อประสิทธิภาพ นอกจากนี้ยังสามารถส่งผลให้เกิดข้อยกเว้น uncaught เมื่อใช้กับคุณสมบัติที่ไม่สามารถกำหนดค่าได้ในโหมดที่เข้มงวด

การละเว้นคุณสมบัติสตริงแบบอิงส่วนที่เหลือ

หมวดหมู่นี้ใช้สำหรับการทำงานกับวัตถุธรรมดาหรืออินสแตนซ์ของอาร์เรย์ในรสชาติ ECMAScript ที่ใหม่กว่าเมื่อต้องการวิธีการที่ไม่กลายพันธุ์และคุณไม่จำเป็นต้องคำนึงถึงคีย์สัญลักษณ์:

const foo = { name: 'KIDDDDD!', [Symbol.for('isCool')]: true }
const { name, ...coolio } = foo // coolio doesn't have "name"
const { isCool, ...coolio2 } = foo // coolio2 has everything from `foo` because `isCool` doesn't account for Symbols :(

การลบคุณสมบัติวัตถุกลายพันธุ์ปลอดภัย

หมวดหมู่นี้ใช้สำหรับปฏิบัติการตามตัวอักษรวัตถุหรืออินสแตนซ์ของวัตถุเมื่อคุณต้องการเก็บ / ดำเนินการต่อเพื่อใช้การอ้างอิงดั้งเดิมในขณะที่ป้องกันข้อยกเว้นที่เกิดขึ้นกับคุณสมบัติที่ไม่สามารถกำหนดค่าได้

'use strict'
const iLikeMutatingStuffDontI = { myNameIs: 'KIDDDDD!', [Symbol.for('amICool')]: true }
Reflect.deleteProperty(iLikeMutatingStuffDontI, Symbol.for('amICool')) // true
Object.defineProperty({ myNameIs: 'KIDDDDD!', 'amICool', { value: true, configurable: false })
Reflect.deleteProperty(iLikeMutatingStuffDontI, 'amICool') // false

นอกจากนี้ในขณะที่การกลายวัตถุในสถานที่ไม่ได้ไร้สัญชาติคุณสามารถใช้ลักษณะการทำงานของReflect.deletePropertyการทำโปรแกรมประยุกต์บางส่วนและเทคนิคการทำงานอื่น ๆ ที่เป็นไปไม่ได้กับdeleteคำสั่ง

การละเว้นคุณสมบัติสตริงตามไวยากรณ์

หมวดหมู่นี้ใช้สำหรับการทำงานกับวัตถุธรรมดาหรืออินสแตนซ์ของอาร์เรย์ในรสชาติ ECMAScript ที่ใหม่กว่าเมื่อต้องการวิธีการที่ไม่กลายพันธุ์และคุณไม่จำเป็นต้องคำนึงถึงคีย์สัญลักษณ์:

const foo = { name: 'KIDDDDD!', [Symbol.for('isCool')]: true }
const { name, ...coolio } = foo // coolio doesn't have "name"
const { isCool, ...coolio2 } = foo // coolio2 has everything from `foo` because `isCool` doesn't account for Symbols :(

การละเว้นคุณสมบัติตามไลบรารี

โดยทั่วไปหมวดหมู่นี้จะช่วยให้มีความยืดหยุ่นในการใช้งานมากขึ้นรวมถึงการบัญชีสำหรับ Symbols & ละเว้นคุณสมบัติมากกว่าหนึ่งรายการในคำสั่งเดียว:

const o = require("lodash.omit")
const foo = { [Symbol.for('a')]: 'abc', b: 'b', c: 'c' }
const bar = o(foo, 'a') // "'a' undefined"
const baz = o(foo, [ Symbol.for('a'), 'b' ]) // Symbol supported, more than one prop at a time, "Symbol.for('a') undefined"

var keyname = "KeyName"; ลบ myObject [keyname];
Vikash Chauhan

7

const myObject = {
        "ircEvent": "PRIVMSG",
        "method": "newURI",
        "regex": "^http://.*"
    };

const { regex, ...other } = myObject;

console.log(myObject)
console.log(regex)
console.log(other)


@CoddWrench ขออภัยฉันไม่ได้สนใจที่จะเห็นคำตอบนั้น delete myObject.regex;ผมตอบได้ทันทีหลังจากที่ได้เห็น
เซียง

7

คุณสามารถใช้การทำลาย ES6 กับผู้ควบคุมเครื่องได้

คุณสมบัติสามารถลบออกได้โดยใช้destructuringร่วมกับผู้ประกอบการส่วนที่เหลือ ในตัวอย่าง regex ของคุณถูกทำลาย (ละเว้น) และคุณสมบัติที่เหลือจะถูกส่งคืนเป็นที่พัก

const noRegex = ({ regex, ...rest }) => rest;
const myObject = {
  "ircEvent": "PRIVMSG",
  "method": "newURI",
  "regex": "^http://.*"
};

console.log(noRegex(myObjext)) //=> {  "ircEvent": "PRIVMSG","method": "newURI" }

หรือคุณสามารถยกเว้นคุณสมบัติแบบไดนามิกเช่นนี้

const myObject = {
  "ircEvent": "PRIVMSG",
  "method": "newURI",
  "regex": "^http://.*"
};
const removeProperty = prop => ({ [prop]: _, ...rest }) => rest

const removeRegex = removeProperty('regex') //=> {  "ircEvent": "PRIVMSG","method":"newURI" }
const removeMethod = removeProperty('method') //=> {  "ircEvent": "PRIVMSG", "regex":"^http://.*" }

7

เราสามารถลบคุณสมบัติใด ๆ จากวัตถุจาวาสคริปต์โดยใช้ต่อไปนี้:

  1. ลบ object.property
  2. ลบวัตถุ ['คุณสมบัติ']

ตัวอย่าง:

var myObject = {
    "ircEvent": "PRIVMSG",
    "method": "newURI",
    "regex": "^http://.*"
};

console.log(myObject);

delete myObject.regex;
console.log('=================');
console.log(myObject);
delete myObject['method'];
console.log('=================');
console.log(myObject);


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.