Как удалить свойство из объекта JavaScript?

6142

Скажем, я создаю объект следующим образом:

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

Каков наилучший способ удалить свойство, regexчтобы закончить с новым myObjectследующим образом?

let myObject = {
    "ircEvent": "PRIVMSG",
    "method": "newURI"
};
johnstok
источник
@EscapeNetscape Это вопрос о поведении, поэтому тест отображает неправильную картину. Конечно, deleteэто будет самый медленный вариант, поскольку это фактическая операция, а не две другие, которые являются просто назначениями. Но суть дела в том , что назначение свойства nullили на undefinedсамом деле не удалить свойство из объекта, но вместо этого устанавливает , что собственность на равную определенную величину постоянной. (Ниже приведены причины, по которым это существенно отличается.)
Abion47,

Ответы:

8309

Нравится:

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 Overflow kangax написал невероятно подробное сообщение в блоге об deleteутверждении в своем блоге « Понимание удаления» . Настоятельно рекомендуется.

nickf
источник
47
Проверено, это также работает с "delete myJSONObject ['regex'];" См .: developer.mozilla.org/en/Core_JavaScript_1.5_Reference/…
johnstok
110
Результатом одного из наблюдений по ссылке «понимание удаления» выше является то, что, поскольку вы не можете обязательно удалить переменную, а только свойства объекта, вы, следовательно, не можете удалить свойство объекта «по ссылке» - var value = obj [ 'проп']; удалить значение // не работает
Dexygen
27
Так что на самом деле это не удалить? Это просто становится неопределенным, но ключ все еще существует? Я что-то пропустил?
Даг Молинью
152
@ Пит нет, это действительно удаляет. Дано: 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
953

Объекты в 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 действительно удаляет его из памяти.
Меандр
8
Кстати, это двойная проблема, чтобы проверить, существует ли свойство в объекте 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.

Array # splice (start [, deleteCount [, item1 [, item2 [, ...]]]])

Array#spliceмутирует массив и возвращает все удаленные индексы. deleteCountэлементы удаляются из индекса startи item1, item2... itemNвставляются в массив из индекса start. Если deleteCountопущен, то элементы из startIndex удаляются до конца массива.

let a = [0,1,2,3,4]
a.splice(2,2) // returns the removed elements [2,3]
// ...and `a` is now [0,1,4]

Существует также же названием, но другой, функция на Array.prototype: Array#slice.

Array # slice ([начало [, конец]])

Array#sliceявляется неразрушающим и возвращает новый массив, содержащий указанные индексы, из startto 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
Этот подход не изменяет исходный объект, на который можно ссылаться в другом месте. Это может или не может быть проблемой, в зависимости от того, как она используется, но об этом следует помнить.
Тамас Чинеге
19
@ B1KMusic Вот способ удалить элемент из массива: splice
wulftone
3
@wulftone nope, который разбивает массив и ничего не делает для удаления значения. Я действительно думаю, что лучший способ удаления из массива, в котором необходимо удалить определенные значения, - это использовать deleteи создать функцию «Сборка мусора» для ее очистки.
Брэден Бест
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);
Koen.
источник
6
Возможно, потому что цель состоит в том, чтобы удалить свойство из объекта, а не создать новое без свойства ... хотя, ваше решение - мое любимое, так как я предпочитаю неизменный способ.
Vingt_centimes
8
В вопросе говорилось «закончить с новым myObject».
Коен.
1
Добавление подчеркивания для удаления свойства засорять ваш проект :) Вместо того , чтобы он доступен , как regexвы могли бы также назначить его на какой - либо другой переменной, например _, то , что используется в таких языках , как Go отбрасывать результат: const { regex: _, ...newObject } = myObject;.
Коен.
2
@PranayKumar Я надеялся, что этот синтаксис сработает; const { [key], ...newObject } = myObject;но это не так, поэтому я не думаю, что это возможно с разрушением.
Коен.
2
С объектами freeze()'d и seal()' d вы не можете просто deleteсоздать свойство. Так что это отличная альтернатива. Хотя в большинстве случаев, вероятно, в любом случае не имеет смысла удалять свойство из замороженного / запечатанного объекта, учитывая, что весь смысл в том, чтобы дать определенные гарантии относительно ваших структур данных, которые этот шаблон будет подрывать. Для тех случаев, когда вам необходимо неразрушающим образом дублировать объект, но без некоторых его свойств, это идеально
Braden Best
119

Синтаксис распространения (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
Readable и short, однако, это может быть не лучшим выбором, если вы работаете с большим количеством объектов, так как его производительность не оптимизирована.

delete obj[key];


Переназначение
Более чем в 2 раза быстрее, чемdelete, однако свойствонеудаляется и может быть повторено.

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


Spread Operator
ЭтотES6оператор позволяет нам возвращать совершенно новый объект, исключая любые свойства, не изменяя существующий объект. Недостатком является то, что он имеет худшую производительность из вышеперечисленных и не рекомендуется использовать, когда вам нужно удалить много свойств одновременно.

{ [key]: val, ...rest } = obj;
Лиор Элром
источник
2
Я думаю, что синтаксис распространения / отдыха для литералов объектов был включен только в ES2018 (ES9), а не в ES6, хотя некоторые движки JS уже реализовали его.
Trincot
2
@trincot Впервые он был представлен в 2014 году ( github.com/tc39/proposal-object-rest-spread ) и представляет собой функцию ES6 (ECMAScript 2015 или ECMAScript 6-е издание). Однако, даже если я ошибаюсь, я не думаю, что это имеет значение для контекста ответа.
Лиор Элром
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())
Джордан Арсено
Хммммм .... Подчеркивание в ~ 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"]

Но дело в том, что если вы заботитесь о памяти и хотите, чтобы весь объект был удален из памяти, рекомендуется установить его в null перед удалением ключа:

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:

Установка свойства в null перед его удалением ничего не делает (если объект не был запечатан Object.seal, и удаление завершилось неудачей. Обычно это не так, если вы специально не пытаетесь).

Чтобы получить больше информации о Object.seal: Object.seal ()

Мехран Хатами
источник
Вы ошибаетесь - только объекты передаются по ссылке в JavaScript, поэтому, если myJSONObject.regexзначение является строкой и вы назначаете его какому-либо другому объекту, у другого объекта есть копия этого значения.
Михал Перлаковский
Вы правы, и это цитата: «быть осторожным с другими ссылками на тот же объект».
Мехран Хатами
43

ECMAScript 2015 (или ES6) поставляется со встроенным объектом Reflect . Удалить свойство объекта можно, вызвав функцию Reflect.deleteProperty () с целевым объектом и ключом свойства в качестве параметров:

Reflect.deleteProperty(myJSONObject, 'regex');

что эквивалентно:

delete myJSONObject['regex'];

Но если свойство объекта не настраивается, его нельзя удалить ни с помощью функции deleteProperty, ни с помощью оператора delete:

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

Object.freeze () делает все свойства объекта неконфигурируемыми (кроме прочего). deletePropertyФункция (а также оператор удаления ) возвращает, 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
madox2
источник
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.
Джоэл Траугер,
@JoelTrauger: Это то, что я говорю ;-)
Джон Слегерс
Да. Мой комментарий заключается в том, что это deleteдаже не должно быть вещью. Это spliceто, что искал ОП.
Джоэл Траугер
1
@JoelTrauger: как я пытался объяснить, deleteдолжен использоваться для свойств объекта и spliceдля элементов массива.
Джон Слегерс
Сплайс действительно медленный. Хотя его следует использовать вместо deleteмассивов, было бы разумно вообще не создавать код, сконцентрированный вокруг него.
Джек Гиффин
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
Это не удаление свойства из объекта, а создание нового объекта без этого свойства.
Джорди
32

Я лично использую Underscore.js или Lodash для манипулирования объектами и массивами:

myObject = _.omit(myObject, 'regex');
Emil
источник
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 };   

И нам нужно удалить «а».

1. С явным ключом реквизита:

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

2. С переменным ключом опоры:

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

Функция стрелки 3.Cool 😎:

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 }
YairTawil
источник
1
Функция гладкой стрелки!
Сильв
27

Использование метода удаления - лучший способ сделать это, согласно описанию MDN, оператор удаления удаляет свойство из объекта. Так что вы можете просто написать:

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

Оператор удаления удаляет данное свойство из объекта. При успешном удалении он вернет true, иначе будет возвращено false. Тем не менее, важно учитывать следующие сценарии:

  • Если свойство, которое вы пытаетесь удалить, не существует, удаление не будет иметь никакого эффекта и вернет true

  • Если в цепочке прототипов объекта существует свойство с таким же именем, то после удаления объект будет использовать свойство из цепочки прототипов (другими словами, удаление влияет только на собственные свойства).

  • Любое свойство, объявленное с помощью var, не может быть удалено из глобальной области или из области функции.

  • Таким образом, delete не может удалять какие-либо функции в глобальной области видимости (будь то часть из определения функции или функция (выражение).

  • Функции, которые являются частью объекта (кроме
    глобальной области), могут быть удалены с помощью delete.

  • Любое свойство, объявленное с помощью let или 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);

Тем не менее, он будет мутировать оригинальный объект. Если вы хотите создать новый объект без указанного ключа, просто назначьте функцию Reduce новой переменной, например:

(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, которую я написал, на случай, если кто-то еще увидит этот пост и подумает, почему это не так просто, как в функции unset 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"}
talsibony
источник
20

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

Например

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

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

Из-за динамической природы JavaScript часто бывают случаи, когда вы просто не знаете, существует свойство или нет. Проверка существования obj перед тем, как && также гарантирует, что вы не выдадите ошибку из-за вызова функции hasOwnProperty () для неопределенного объекта.

Извините, если это не добавилось к вашему конкретному варианту использования, но я считаю, что это хороший дизайн для адаптации при управлении объектами и их свойствами.

Willem
источник
2
delete foo.bar работает, даже если bar не существует, поэтому ваш тест слишком сложен, ИМХО.
PhiLho
@PhiLho, это зависит от того, где вы используете JavaScript. Я считаю, что в Node.js это приводит к сбою вашего сервера.
Виллем
2
delete foo.bar;Исключение выдается только в том случае, если foo ложно или если вы находитесь в строгом режиме, а foo является объектом с неконфигурируемым свойством bar.
Macil
Я не помню точную проблему, которая у меня была с этим, но я думаю, что проблема может появиться, когда самого foo не существует, и вы пытаетесь удалить его свойство.
Виллем
Да, вы должны проверить, существует ли foo, иначе foo.bar сгенерирует исключение, но вам не нужно проверять существование для bar перед его удалением. Это слишком большая часть моего комментария. :-)
PhiLho
16

Используя ramda # disoc, вы получите новый объект без атрибута regex:

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

Вы также можете использовать другие функции для достижения того же эффекта - опустить, выбрать, ...

Amio.io
источник
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: {}}}
ayushgp
источник
Эта функция работает как шарм, но зачем нам возвращать true и возвращать false? Моя версия кода: codepen.io/anon/pen/rwbppY . Моя версия потерпит неудачу в любом случае?
обычно
@ witty2017 это не подведет. Место, где я использовал функцию, также нужно было проверить, существует ли свойство уже или нет. если свойство не существует, оно вернет false. Если он найдет свойство и удалит его, он вернет true.
ayushgp
8

Вы можете просто удалить любое свойство объекта, используя deleteключевое слово.

Например:

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

Например, чтобы удалить любое свойство, key1используйте deleteключевое слово, например:

delete obj.key1

Или вы также можете использовать массивную запись:

delete obj[key1]

Ссылка: 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"];
        }
    }
);

xgqfrms-gildata
источник
7

Утверждение Дэна о том, что «удаление» очень медленное, и опубликованный им тест были поставлены под сомнение. Итак, я провел тест самостоятельно в Chrome 59. Кажется, что «delete» примерно в 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);

ideaboxer
источник
SyntaxError: Unexpected token '...'. Expected a property name.?
Кшиштоф Пшигода
Попробуйте это с помощью современного браузера, такого как Firefox, Chromium или Safari. И я ожидаю, что это будет работать и с Edge.
ideaboxer
В качестве альтернативы, если ваши клиенты заставляют вас поддерживать устаревшие браузеры, вы можете рассмотреть возможность использования 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"
james_womack
источник
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;.
сян
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);

Рави Ранджан
источник