Як видалити властивість з об’єкта JavaScript?


6139

Скажіть, я створюю об'єкт так:

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

Який найкращий спосіб видалити властивість regexі закінчити нове myObjectнаступним чином?

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


@EscapeNetscape Це питання щодо поведінки, тому тест малює неправильну картину. Звичайно, це deleteбув би найповільніший варіант, оскільки це фактична операція, а не два інших, які є просто простими завданнями. Але суть справи полягає в тому, що присвоєння властивості nullабо undefinedфактично не видаляє властивість з об'єкта, а натомість встановлює це властивість рівним певній постійній величині. (Нижче відповіді наводять причини, чому це суттєва різниця.)
Авіон47

Відповіді:


8298

Подобається це:

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);

Для всіх, хто зацікавлений читати більше про нього, користувач Kangax Stack Overflow написав неймовірно глибоку публікацію в блозі про deleteзаяву в своєму блозі " Розуміння видалення" . Настійно рекомендується.


47
Поставлено прапорець, він також працює з "delete myJSONObject ['regex'];" Дивіться: developer.mozilla.org/en/Core_JavaScript_1.5_Reference/…
johnstok

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 */
Подано

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 працюватиме лише над властивостями, дескриптор яких позначає їх як настроювані.


43
властивість, призначена невизначеному, все-таки є властивістю об'єкта, тому GC не буде видалена, якщо не буде неправильно прочитаний останній абзац.
Ленс

8
Я помилявся торкатися теми GC тут. Обидва способи мають однаковий результат для GC: вони видаляють значення, пов'язане з ключем. Якби це значення було останньою посиланням на якийсь інший об'єкт, цей об’єкт буде очищено.
Дан

15
властивість, призначена невизначеному, все-таки є властивістю об'єкта, тому GC не буде видалено GC не керує нічого щодо властивостей. Він збирає та видаляє значення. Поки більше нічого не посилається на якесь значення (об'єкт, рядок тощо), GC видаляє його з пам'яті.
meandre

8
BTW, це подвійна проблема перевірити, чи існує властивість на об'єкті Javascript. Використання в операторах є надійним , але повільно. Перевірте, чи властивість не визначено, "це не правильна відповідь", але це шлях швидше. перевірка
rdllopes

8
Ця відповідь все ще актуальна? JSPerf в даний час вниз, але цей тест , здається, вказує , що різниця в швидкості складає всього 25%, що ніде близько до «~ 100 разів повільніше» в цій відповіді.
Чербр

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.

Масив # сплайс (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.

Масив # фрагмент ([початок [, кінець]])

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видаляє останній елемент з масиву та повертає цей елемент. Ця операція змінює довжину масиву.


12
Цей підхід не модифікує оригінальний об'єкт, на який може бути ще посилання в іншому місці. Це може бути або не бути проблемою в залежності від того, як він використовується, але це щось, що слід пам’ятати.
Тамас Цінеге

19
@ B1KMusic Ось спосіб , щоб видалити елемент з масиву: зрощування
wulftone

3
@wulftone nope, який розбиває масив і нічого не робить для видалення значення. Я дійсно думаю, що найкращий спосіб видалити з масиву, де потрібно видалити конкретні значення, - це використовувати deleteта зробити функцію збору сміття для її очищення.
Braden Best

5
Я не бачу spliceу вашій редакції, але це removeповинно бутиArray.prototype.remove = function(index) { this.splice(index, 1); };
Ry-

1
Ця стаття сповнена бика 1. Вона не стосується питання! 2. Це зразкове неправильне використання мови та скарга на те, що "це не працює!" 3. Не звинувачуйте оператора видалення JavaScript в ідіосинкратичній помилці Крокфорда у введенні null для індексу порожнього масиву. Він не розуміє значення нуля - вважає, що це помилка. Помилка - його власна і одна - у видаленому значенні заданого індексу масиву немає нуля. У масиві немає «дірки» - це порожній індекс. Абсолютно законний і очікуваний.
Бекім Бакай

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ви могли б також призначити його на який - небудь інший змінної, наприклад _, то , що використовується в таких мовах , як Go відкидати результат: const { regex: _, ...newObject } = myObject;.
Коен.

2
@PranayKumar Я сподівався, що цей синтаксис спрацює; const { [key], ...newObject } = myObject;але це не так, тому я не думаю, що це можливо з руйнуванням.
Коен.

2
З об'єктами freeze()'d і seal()' d ви не можете просто deleteвласність. Тож це відмінна альтернатива. Хоча в більшості випадків, мабуть, не буде сенсу видаляти властивість із замороженого / запечатаного об'єкта, враховуючи, що вся суть полягає у наданні певних гарантій щодо ваших структур даних, з-за яких ця схема буде підривати. Для тих випадків, коли вам потрібно не руйнувати об єкт, але без деяких його властивостей, це ідеально
Бреден Бест

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).


РОЗШИРЕНИЙ ВІДПОВІДЬ common
Існує кілька загальних способів видалення властивості з об’єкта.
У кожного є свої плюси і мінуси ( перевірте це порівняння ефективності ):

Видалити оператора "
Чітке та коротке", однак це може бути не найкращим вибором, якщо ви працюєте над великою кількістю об'єктів, оскільки його ефективність не оптимізована.

delete obj[key];


Перепризначення
Більше ніж у 2 рази швидшеdelete, проте властивістьневидаляється і її можна повторити.

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


Оператор розповсюдження
ЦейES6оператор дозволяє нам повернути абсолютно новий об’єкт, виключаючи будь-які властивості, без мутації існуючого об'єкта. Мінус полягає в тому, що він має гірші показники, ніж вищезгадане, і не рекомендується використовувати його, коли потрібно видалити багато властивостей одночасно.

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

2
Я думаю, що синтаксис розповсюдження / спокою для літералів об'єктів був включений лише в ES2018 (ES9), а не в ES6, хоча декілька двигунів JS вже реалізували його.
трінкот

2
@trincot Він був вперше представлений у 2014 році ( github.com/tc39/proposed-object-rest-spread ), і це функція ES6 (ECMAScript 2015 aka ECMAScript 6th Edition). Однак, навіть якщо я помиляюся, я не думаю, що це має значення для контексту відповіді.
Ліор Елром

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

Хмммм .... Підкреслення на 100 разів повільніше, ніж на delete obj[prop]100 разів повільніше obj[prop] = undefined.
Джек Гіффін

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 передаються посиланням у JavaScript, тому якщо myJSONObject.regexзначення '' є рядком і ви присвоюєте його якомусь іншому об'єкту, інший об'єкт має копію цього значення.
Michał Perłakowski

Ви маєте рацію, і це цитата: "будьте обережні щодо інших ваших посилань на той самий об'єкт".
Мехран Хатамі

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також зіпсує вашу індексацію.

Отже, видаляючи значення з об’єкта, завжди спочатку враховуйте, чи маєте ви справу зі властивостями об'єкта чи маєте справу зі значеннями масиву, і вибирайте відповідну стратегію на основі цього.

Якщо ви хочете поекспериментувати з цим, ви можете використовувати цей Fiddle як вихідний пункт.


Я думаю, що ви завжди повинні використовувати spliceв масиві замість delete.
Джоель Траугер

@JoelTrauger: Ось що я говорю ;-)
Джон Slegers

Так. Мій коментар полягає в тому, що deleteце навіть не повинно бути річчю. Це spliceте, що шукала ОП.
Джоель Траугер

1
@JoelTrauger: Як я намагався пояснити, його deleteслід використовувати для властивостей об'єкта та spliceдля елементів масиву.
John Slegers

Сплайс справді повільний. Хоча його слід використовувати замість deleteмасивів, наймудріше взагалі не створювати код, зосереджений навколо нього.
Джек Гіффін

39

Використання ES6:

(Деструктуризація + оператор розповсюдження)

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

Я не думаю, що це особливість ES6, але така, яка була включена лише до ES9.
трінкот

Тож фактично ви не використовуєте ES6, як пишете, але ES9 ... ;-)
trincot

2
Це не вилучення властивості з об’єкта, а створення нового об'єкта без цього властивості.
Джорді Небот


31

Оператор видалення - найкращий спосіб зробити це.

Живий приклад для показу:

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

Можливо, варто зауважити, що, хоча використання deleteоператора є здоровим щодо вивезення сміття , воно може бути несподівано повільним , нічим не малим, з тієї ж причини.
Джон Вайс

29

Щоб клонувати об’єкт без власності:

Наприклад:

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

І нам потрібно видалити 'a'.

1.З явним опорним ключем:

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

2.З змінним опорним ключем:

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

Використання методу delete - найкращий спосіб зробити це, згідно з описом 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

Цей пост дуже старий, і я вважаю це дуже корисним, тому я вирішив поділитися функцією скидання, яку я написав, якщо хтось ще побачить цю публікацію і подумає, чому це не так просто, як це у функції скидання PHP.

Причиною написання цієї нової 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

Тут є багато хороших відповідей, але я просто хочу зазвучити в тому, що під час використання delete для видалення властивості в JavaScript часто буває спочатку перевірити, чи існує ця властивість, щоб запобігти помилкам.

Напр

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

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

Через динамічний характер JavaScript часто трапляються випадки, коли ви просто не знаєте, чи існує властивість чи ні. Перевірка наявності Obj до && також гарантує, що ви не кинете помилку через виклик функції hasOwnProperty () на невизначений об'єкт.

Вибачте, якщо це не додало до вашої конкретної справи використання, але я вважаю, що це хороша конструкція для адаптації при керуванні об'єктами та їх властивостями.


2
delete foo.bar працює, навіть якщо бар не існує, тому ваш тест трохи забагато, IMHO.
PhiLho

@PhiLho, що залежить від того, де ви користуєтеся JavaScript. В Node.js я вважаю, що це призводить до збою вашого сервера.
Віллем

2
delete foo.bar;виняток викидає лише, якщо foo є фальшивим, або якщо ви перебуваєте в суворому режимі, а foo - це об'єкт з неконфігурованою властивістю смуги.
Маціл

Я не пам’ятаю точної проблеми, з якою у мене виникло це, але я думаю, що проблема може з’явитися, коли foo сам не існує, і ви намагаєтесь видалити його властивість.
Віллем

Так, вам доведеться перевірити, чи існує foo, інакше foo.bar викине виняток, але вам не потрібно перевіряти наявність бар для того, щоб видалити його. Це "занадто багато" частини мого коментаря. :-)
PhiLho

16

Використовуючи ramda # dissoc, ви отримаєте новий об’єкт без атрибута regex:

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

Ви також можете використовувати інші функції для досягнення такого ж ефекту - опустити, вибрати, ...


15

Спробуйте наступний метод. Призначте Objectзначення властивості undefined. Тоді stringifyоб’єкт і parse.

 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: {}}}

Ця функція працює як шарм, але для чого нам потрібно повернути true та повернути false? Моя версія коду: 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.?
Кшиштоф Пшигода

Спробуйте це з сучасним браузером, таким як Firefox, Chromium або Safari. І я очікую, що це також буде працювати з Edge.
ідеалбоксер

Як альтернатива, якщо ваші клієнти змушують вас підтримувати застарілі браузери, ви можете розглянути можливість використання TypeScript, який перетворює ваш код у застарілий синтаксис (+ надає перевагу безпеки статичного типу).
ideaboxer

7

Видалення власності в JavaScript

На цій сторінці представлено багато різних варіантів не тому, що більшість варіантів є неправильними, або тому, що відповіді є дублікатами, а тому, що відповідна методика залежить від ситуації, в якій ви знаходитесь, та цілей завдань, які ви та / або ви команда намагається виконати. Щоб відповісти на запитання однозначно, потрібно знати:

  1. Версія ECMAScript, на яку ви орієнтовані
  2. Діапазон типів об'єктів, на яких потрібно видалити властивості, та тип імен властивостей, які потрібно мати, щоб опустити (Тільки рядки? Символи? Слабкі посилання, відображені з довільних об’єктів? Все це були типи покажчиків властивостей у JavaScript вже протягом багатьох років )
  3. Етокси / схеми програмування, які ви та ваша команда використовуєте. Ви віддаєте перевагу функціональним підходам, і мутація є багатослівною у вашій команді, або ви використовуєте мутативні об'єктно-орієнтовані методи дикого заходу?
  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, за винятком першої версії. Однак, це мутація, яка порушує деякі принципи програмування та має наслідки для продуктивності. Це також може призвести до вимкнутих винятків при використанні неконфігуруваних властивостей у суворому режимі .

Опущення властивості рядка на основі відпочинку

Ця категорія призначена для роботи в екземплярах простого об'єкта або масиву в новіших смаках ECMAScript, коли потрібен немутативний підхід і вам не потрібно обліковувати клавіші Symbol:

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, коли потрібен немутативний підхід і вам не потрібно обліковувати клавіші Symbol:

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 :(

Бездіяльність власності на основі бібліотеки

Ця категорія, як правило, дозволяє забезпечити більшу функціональну гнучкість, включаючи облік символів та опущення більше одного властивості в одному виписці:

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 [ім'я ключа];
Вікаш Чаухан

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;.
xiang

7

Ви можете використовувати руйнування ES6 з оператором відпочинку.

Властивості можна видалити за допомогою руйнування в поєднанні з оператором відпочинку . У вашому прикладі регулярний вираз деструктурується (ігнорується), а решта властивостей повертається як спокій.

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

Ми можемо видалити будь-яке властивість з об’єкта javascript, використовуючи наступне:

  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);


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.