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

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

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

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

var myObject = {
    "ircEvent": "PRIVMSG",
    "method": "newURI"
};
4948
задан johnstok 16 окт. '08 в 13:57
источник поделиться
35 ответов
  • 1
  • 2

Вот так:

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

Demo

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

console.log(myObject);

Для всех, кто интересуется большей информацией об этом, пользователь Qaru kangax написал невероятно подробное сообщение в блоге о заявлении delete в своем блоге, Понимание удаления. Настоятельно рекомендуется.

6880
ответ дан nickf 16 окт. '08 в 13:58
источник поделиться

delete оператора неожиданно замедляется!

Посмотрите на бенчмарк.

Удалить - единственный верный способ удалить свойства объекта без каких-либо остатков, но он работает ~ в 100 раз медленнее, по сравнению с его "альтернативным", устанавливающим object[key] = undefined.

Эта альтернатива не является правильным ответом на этот вопрос! Но, если вы используете его с осторожностью, вы можете значительно ускорить некоторые алгоритмы. Если вы используете delete в циклах, и у вас проблемы с производительностью, прочитайте подробное объяснение.

Когда следует использовать delete и когда заданное значение undefined?

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

Используйте delete , когда вы передаете объект результата в код, на котором у вас нет контроля (или когда вы не уверены в своей команде или себе).

Он удаляет ключ из хэш-карты.

 var obj = {
     field: 1     
 };
 delete obj.field;

Если вы не уверены в производительности, используйте параметр undefined. Это может серьезно повлиять на ваш код.

Ключ остается на своем месте в hashmap, только значение заменяется undefined. Поймите, что for..in цикл все равно будет перебирать этот ключ.

 var obj = {
     field: 1     
 };
 obj.field = undefined;

Используя этот метод, не все способы определения свойства существования будут работать, как ожидалось.

Однако этот код:

object.field === undefined

будут вести себя эквивалентно для обоих методов.

тесты

Подводя итог, существуют различия в способах определения существования свойства и for..in цикла for..in.

 console.log('* -> "Takes prototype inheritance into consideration, that means it lookups all over prototype chain too."');

 console.log(obj.field === undefined, 'obj.field === undefined', 'You get "undefined" value when querying for "field" in object-hashmap. *');

 console.log(obj["field"] === undefined, 'obj["field"] === undefined', 'Just another way to query (equivalent). *');

 console.log(typeof obj.field === "undefined", 'typeof obj.field === "undefined"', 'Get the value attached to "field" key, and check it\ type is "undefined". *');

 console.log("field" in obj, '"field" in obj', 'This statement returns true if "field" key exists in the hashmap. False otherwise. *');

 console.log(obj.hasOwnProperty("field"), 'obj.hasOwnProperty("field")', 'This statement returns true if \'field\' key exists in the hashmap. The ONLY way NOT to lookup for property in the prototype chain!');
 //Object.keys().indexOf() is an overkill that runs much slower :)

 var counter = 0,
     key;
 for (key in obj) {
     counter++;
 }
 console.assert(counter === 0, 'counter === 0', '"field" is not iterated using "for .. in" loop. *');

Остерегайтесь утечек памяти!

Хотя obj[prop] = undefined быстрее, чем delete obj[prop], еще одно важное соображение состоит в том, что obj[prop] = undefined не всегда может быть уместным. delete obj[prop] удаляет prop из obj и стирает его из памяти, тогда как obj[prop] = undefined просто устанавливает значение prop для undefined которое оставляет prop еще в памяти. Поэтому в ситуациях, когда существует много ключей, которые создаются и удаляются, использование obj[prop] = undefined может привести к дорогостоящей согласованности памяти (заставляя страницу замерзать) и потенциально ошибке вне памяти. Изучите следующий код.

"use strict";
var theNodeList=[], i, current, numberOfNodes=65536, body=document.body, nodeRecords=[];
for (i = 0; i !== numberOfNodes; i++) {
    nodeRecords[i] = [];
    current = theNodeList[i] = document.createElement("div");
    current.textContent = i;
    document.body.appendChild( current );
}
var lastTime = -1;
requestAnimationFrame(function recordUpdates(){
    var currentTime = Math.round( performance.now()*1000 )
    for (i = 0; i !== numberOfNodes; i++) {
        if (lastTime !== -1) {
            // the previously collected data is no longer in use
            /*************************************************/
            /****/ nodeRecords[i][lastTime] = undefined; /****/
            /*************************************************/
        }
        nodeRecords[i][currentTime] = theNodeList[i].outerHTML;
    }
    lastTime = currentTime;
    requestAnimationFrame( recordUpdates );
});

В приведенном выше коде просто делается nodeRecords[i][lastTime] = undefined; приведет к массивной утечке памяти из-за каждого кадра анимации. Каждый кадр, все элементы 65536 DOM будут занимать еще 65536 отдельных слотов, но предыдущие слоты 65536 будут установлены только на неопределенные, что оставляет их висящими в памяти. Продолжайте, попробуйте запустить вышеуказанный код в консоли и убедитесь сами. После принудительной ошибки из-за памяти попытайтесь запустить ее заново, за исключением следующей версии кода, в которой вместо этого используется оператор delete.

"use strict";
var theNodeList=[], i, current, numberOfNodes=65536, body=document.body, nodeRecords=[];
for (i = 0; i !== numberOfNodes; i++) {
    nodeRecords[i] = [];
    current = theNodeList[i] = document.createElement("div");
    current.textContent = i;
    document.body.appendChild( current );
}
var lastTime = -1;
requestAnimationFrame(function recordUpdates(){
    var currentTime = Math.round( performance.now()*1000 )
    for (i = 0; i !== numberOfNodes; i++) {
        if (lastTime !== -1) {
            // the previously collected data is no longer in use
            /********************************************/
            /****/ delete nodeRecords[i][lastTime]; /****/
            /********************************************/
        }
        nodeRecords[i][currentTime] = theNodeList[i].outerHTML;
    }
    lastTime = currentTime;
    requestAnimationFrame( recordUpdates );
});

Как видно из приведенного выше фрагмента кода, существуют некоторые редкие подходящие варианты использования для оператора delete. Однако не беспокойтесь об этой проблеме слишком много. Это станет проблемой только с объектами продолжительной жизни, которые постоянно добавляют к ним новые ключи. В любом другом случае (это почти каждый случай в реальном программировании), наиболее целесообразно использовать obj[prop] = undefined. Основная цель этого раздела - просто обратить ваше внимание на то, чтобы в редких случаях это стало проблемой в вашем коде, тогда вы можете более легко понять проблему и, следовательно, не тратить время на анализ своего кода, чтобы найти и понять эту проблему.

Не всегда задано для undefined

Одним из аспектов Javascript, который важно рассмотреть, является полиморфизм. Полиморфизм - это присвоение одинаковых переменных/слотов в объектах разных типов, как показано ниже.

var foo = "str";
foo = 100;          // variable foo is now labeled polymorphic by the browser
var bar = ["Some", "example"];
bar[2] = "text";    // bar is a monomorphic array here because all its entries have the
                    // same type: string primitive
bar[1] = undefined; // bar is now a polymorphic array

Тем не менее, существуют две основные проблемы, которые невозможно устранить при использовании полиморфных массивов:

  1. Они медленны и неэффективны. При доступе к определенному индексу вместо того, чтобы просто получать глобальный тип для массива, браузер вместо этого должен получать тип на основе индекса, в котором каждый индекс хранит дополнительные метаданные его типа.
  2. После полиморфного, всегда полиморфного. Когда массив сделан полиморфным, полиморфизм не может быть отменен в браузерах Webkit. Таким образом, даже если вы восстановите полиморфный массив как неполиморфный, он все равно будет храниться браузером в виде полиморфного массива.

Можно уподобить полиморфизм наркотической зависимости. На первый взгляд, это кажется невероятно прибыльным: красивый довольно пушистый код. Затем кодер вводит свой массив в препарат полиморфизма. Мгновенно полиморфная матрица становится менее эффективной, и она никогда не может стать столь же эффективной, как и раньше, с тех пор, как она наркотизирована. Чтобы соотнести такое обстоятельство с реальной жизнью, кто-то из кокаина может даже не иметь возможности управлять простой дверной ручкой, а тем более не в состоянии рассчитать цифры PI. Аналогично, массив на препарате полиморфизма не может быть столь эффективным, как мономорфный массив.

Но, как аналогия с наркотиками относится к операции delete? Ответ содержит последнюю строку кода в приведенном выше фрагменте. Таким образом, пусть это будет пересмотрено, на этот раз с завихрением.

var bar = ["Some", "example"];
bar[2] = "text";    // bar is not a polymorphic array here because all its entries have the
                    // same type: string primitive
bar[1] = "";        // bar is still a monomorphic array
bar[1] = undefined; // bar is now a polymorphic array

Обратите внимание. bar[1] = "" не вызывает полиморфизм, тогда как bar[1] = undefined делает. Поэтому всегда следует, когда это возможно, использовать соответствующий тип для своих объектов, чтобы случайно не вызвать полиморфизм. Один из таких лиц может использовать следующий список в качестве общей ссылки, чтобы получить их. Однако, пожалуйста, не используйте явно указанные ниже идеи. Вместо этого используйте все, что хорошо работает для вашего кода.

  • При использовании массива/переменной, введенной в булевский примитив, используйте значение false или undefined как пустое значение. Хотя избежать ненужного полиморфизма хорошо, переписывание всего вашего кода, чтобы явно запретить его, скорее всего, приведет к снижению производительности. Используйте здравое суждение!
  • При использовании массива/переменной, введенной в числовой примитив, используйте 0 в качестве пустого значения. Обратите внимание, что внутри есть два типа чисел: быстрые целые числа (от 2147483647 до -2147483648 включительно) и медленные двойные точки с плавающей запятой (что угодно, кроме NaN и Infinity). Когда целое число понижается до двойника, его нельзя отнести к целому числу.
  • При использовании массива/переменной, введенной в строковый примитив, используйте "" в качестве пустого значения.
  • При использовании Символа, подождите, почему вы используете Символ?!?! Символы плохой juju для исполнения. Все запрограммированные на использование Символы могут быть перепрограммированы, чтобы не использовать символы, что приводит к более быстрому коду без символов. Символы - это действительно просто неэффективный мета-сахар.
  • При использовании чего-либо еще используйте null.

Однако будьте внимательны! Не начинайте делать это со всем существующим кодом, поскольку он, скорее всего, сломает такой существующий код и/или представит странные ошибки. Скорее, такая эффективная практика должна быть реализована с самого начала, а при преобразовании существующего кода рекомендуется дважды, тройная, четырехкратная проверка всех строк, относящихся к этому, как попытка обновить старый код до этой новой практики, может быть как рискованно, так как это полезно.

710
ответ дан Dan 12 февр. '14 в 20:48
источник поделиться

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

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

Это работает в Firefox и Internet Explorer, и я думаю, что это работает во всех остальных.

195
ответ дан redsquare 16 окт. '08 в 14:03
источник поделиться

Обновление 2018-07-21: Долгое время я испытывал смущение в связи с этим ответом, поэтому считаю, что я немного прикоснулся к нему. Просто небольшой комментарий, разъяснение и форматирование, чтобы ускорить чтение ненужных длинных и запутанных частей этого ответа.


КОРОТКАЯ ВЕРСИЯ

Фактический ответ на вопрос

Как говорили другие, вы можете использовать delete.

obj // {"foo": "bar"}
delete obj["foo"]
obj // {}
obj["foo"] // undefined

Массивный эквивалент

Не delete из массива. Array.prototype.splice этого используйте Array.prototype.splice.

arr // [1,2,3,4,5]
arr.splice(3,1); // 4
arr // [1,2,3,5]

ДЛИННАЯ ВЕРСИЯ

JavaScript - это язык ООП, поэтому все это объект, включая массивы. Таким образом, я считаю необходимым указать на конкретное предостережение.

В массивах, в отличие от простых старых объектов, использование delete оставляет за мусором в форме null, создавая "дыру" в массиве.

var array = [1, 2, 3, 4];
delete array[2];
/* Expected result --> [1, 2, 4]
 * Actual result   --> [1, 2, null, 4]
 */

Как вы можете видеть, delete не всегда работает так, как можно было бы ожидать. Значение перезаписывается, но память не перераспределяется. Другими словами, array[4] не перемещается в array[3]. В отличие от Array.prototype.unshift, который вставляет элемент в начало массива и сдвигает все вверх (array[0] становится array[1] и т.д.),

Честно говоря, помимо установки null а не undefined --which, это совершенно странно - это поведение не должно удивлять, поскольку delete - это унарный оператор, такой как typeof, который жестко вкручен в язык и не должен заботиться о типе используемого объекта, тогда как Array является подклассом Object с методами, специально предназначенными для работы с массивами. Поэтому нет никаких оснований для delete чтобы иметь специальный случай, приготовленный для повторного смещения массива, поскольку это просто замедлит работу с ненужной работой. Оглядываясь назад, мои ожидания были нереалистичными.

Конечно, это меня удивило. Потому что я написал это, чтобы оправдать мой крестовый поход против "нулевого мусора":

Игнорируя опасности и проблемы, присущие null, и пространство впустую, это может быть проблематично, если массив должен быть точным.

Который является ужасным оправданием для избавления от null s-- null является опасным только при неправильном использовании и не имеет ничего общего с "точностью". Настоящая причина, по которой вы не должны delete из массива, заключается в том, что оставляя заполненные мусором и грязные структуры данных вокруг, неаккуратно и подвержено ошибкам.

Ниже приведен надуманный сценарий, который становится довольно длинным, поэтому вы можете перейти к разделу "Решение", если хотите. Единственная причина, по которой я покидаю этот раздел, - это то, что я думаю, что некоторые люди, вероятно, считают это забавным, и я не хочу быть "тем парнем", который отправляет "смешной" ответ, а затем удаляет из него все "смешные",

... Это глупо, я знаю.

Надуманный и долгосрочный сценарий PDP-11

Например, предположим, что вы создаете webapp, который использует JSON-сериализацию для хранения массива, используемого для "вкладок" в строке (в данном случае, localStorage). Пусть также говорят, что код использует числовые индексы элементов массива для "названия" их при рисовании на экране. Почему вы делаете это, а не просто сохраняете "титул"? Потому что... причины.

Хорошо, позвольте сказать, что вы пытаетесь сохранить память по просьбе этого одного пользователя, который запускает миникомпьютер PDP-11 с 1960 года, работающего под управлением UNIX, и написал собственный собственный интерфейс, совместимый с JavaScript, с поддержкой JavaScript браузера, потому что X11 не может быть и речи.

Все более и более глупый сценарий краевого сценария, используя delete в указанном массиве, приведет к null загрязнению массива и, вероятно, приведет к появлению ошибок в приложении позже. И если вы проверите null, оно будет автоматически пропускать числа, в результате чего отображаемые вкладки будут выглядеть как [1] [2] [4] [5]...

if (array[index] == null)
    continue;
else
    title = (index + 1).toString();
/* 0 -> "1"
 * 1 -> "2"
 * 2 -> (nothing)
 * 3 -> "4"
 */

Да, это определенно не то, что вы хотели.

Теперь вы можете сохранить второй итератор, например j, для увеличения только тогда, когда действительные значения считываются из массива. Но это точно не решит null проблему, и вам все равно понравится этот пользователь Troll PDP-11. Увы, у его компьютера просто недостаточно памяти для хранения этого последнего целого числа (не спрашивайте, как ему удается обрабатывать массив переменной ширины...).

Итак, он посылает вам письмо в гневе:

Hey, your webapp broke my browser! I checked my localStorage database after your stupid code made my browser segfault, and this is what I found:

>"tabs:['Hello World', 'foo bar baz', null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, ... ]"

After clearing my precious data, it segfaulted again, and I did a backtrace, and what do I find? WHAT DO I FIND!? YOU USE TOO MANY VARIABLES!

>var i = index;
>var j = 1;

Grr, I am angry now.
-Troll Davidson

Теперь вы на своем конце. Этот парень постоянно жаловался на ваше приложение, и вы хотите сказать ему, чтобы он заткнулся и пошел на лучший компьютер.

Решение: Array.prototype.splice

К счастью, массивы имеют специальный метод для удаления индексов и перераспределения памяти: Array.prototype.splice(). Вы могли бы написать что-то вроде этого:

Array.prototype.remove = function(index){
  this.splice(index,1);
}
...
array = [1, 2, 3, 4];
array.remove(2);
// Result -> [1, 2, 4]

И просто так, вы довольны г-ном PDP-11. Ура! (Я бы все же сказал ему, хотя...)

Array.prototype.splice vs Array.prototype.slice

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

Array.prototype.splice (начало, n)

.splice() мутирует массив и возвращает удаленные индексы. Массив нарезается, начиная с индекса, start и n элементов вырезаются. Если n не указано, весь массив после start n = array.length - start (n = array.length - start).

let a = [5,4,3,2,1];
let chunk = a.splice(2,2);

// a     [5,4,3,2,1]
// start  0 1 2 - -
// n      - - 1 2 -

chunk; // [3,2]
a;     // [5,4,1]

Array.prototype.slice (начало, конец)

.slice() является неразрушающим и возвращает новый массив, содержащий указанные индексы от start до end. Если end оставлен неуказанным, поведение будет таким же, как .splice() (end = array.length). Поведение немного сложно, поскольку по какой-то причине end индексы от 1 вместо 0. Я не знаю, почему это происходит, но так оно и есть. Кроме того, если end <= start, результатом будет пустой массив.

let a = [5,4,3,2,1];
let chunks = [
    a.slice(2,0),
    a.slice(2,2),
    a.slice(2,3),
    a.slice(2,5) ];

// a             [5,4,3,2,1]
// start          0 1 2 - -
// end, for...    - - - - -
//   chunks[0]  0 - - - - -   
//   chunks[1]    1 2 - - -
//   chunks[2]    1 2 3 - -
//   chunks[3]    1 2 3 4 5

chunks; // [ [], [], [3], [3,2,1] ]
a;      // [5,4,3,2,1]

На самом деле это не то, что происходит, но легче думать об этом. Согласно MDN, вот что происходит на самом деле:

// a             [5,4,3,2,1]
// start          0 1 2 - - -
// end, for...    - - - - - -
//   chunks[0]    0 - - - - -
//   chunks[1]    0 1 2 - - -
//   chunks[2]    0 1(2)3 - -
//   chunks[3]    0 1(2 3 4)5

Индекс, указанный end, просто исключается из среза. Обозначенные в скобках индексы указывают, что нарезается. В любом случае, поведение не является интуитивным и связано с тем, что он вызывает свою справедливую долю ошибок "один за другим", поэтому вам может показаться полезным сделать функцию-оболочку более .splice() поведения .splice():

function ez_slice(array, start = 0, n = null){
    if(!Array.isArray(array) || !is_number(start))
        return null;

    if(is_number(n))
        return array.slice(start, start + n);

    if(n === null)
        return array.slice(start);

    return null;
}

ez_slice([5,4,3,2,1], 2, 1) // [3]
ez_slice([5,4,3,2,1], 2)    // [3,2,1]

/* Fun fact: isNaN is unreliable.
 * [NaN, [], {}, 0, 1, Infinity, undefined, null, "Hi"].filter(isNaN)
 * [NaN, {}, undefined, "Hi"]
 *
 * What we want is...
 *
 * [NaN, [], {}, 0, 1, Infinity, undefined, null, "Hi"].filter(is_nan)
 * [NaN]
 */
function is_nan(num){
    return typeof num === "number"
        && num !== num;
}

function is_number(num){
    return !is_nan(num)
        && typeof num === "number"
        && isFinite(num);
}

Обратите внимание, что функция-обертка предназначена для очень строгих типов и возвращает значение null если что-то отключено. Это включает в себя строку типа "3". Остается программисту усердно относиться к его типам. Это должно способствовать хорошей практике программирования.

Обновление относительно is_array()

Это относится к этому (теперь удаленному) фрагменту:

function is_array(array){
    return array !== null
        && typeof array === "object"
        && typeof array.length !== "undefined"
        && array.__proto__ === Array.prototype;
}

Итак, как оказалось, на самом деле есть встроенный способ определить, действительно ли массив является массивом, и это Array.isArray(), введенный в ECMAScript 5 (декабрь 2009 г.). Я нашел это, глядя на вопрос, есть ли вопрос о том, чтобы сообщать массивы с объектов, чтобы увидеть, было ли лучшее решение, чем мое, или добавить мое, если их не было. Итак, если вы используете версию JavaScript, которая раньше ECMA 5, там ваш полипол. Тем не менее, я настоятельно рекомендую не использовать is_array(), так как продолжение поддержки старых версий JavaScript означает продолжение поддержки старых браузеров, которые их реализуют, что означает поощрение использования небезопасного программного обеспечения и помещение пользователей под угрозу для вредоносного ПО. Поэтому, пожалуйста, используйте Array.isArray(). Используйте let и const. Используйте новые функции, которые добавляются в язык. Не используйте префиксы поставщиков. Удалите это полисплощадку IE с вашего сайта. Удалите этот XHTML <!CDATA[[... crap, тоже - мы переместились в HTML5 еще в 2014 году.). Чем раньше все откажутся от поддержки этих старых/эзотерических браузеров, тем скорее поставщики браузеров будут действительно следовать веб-стандарту и охватывают новые технологии, и чем скорее мы сможем перейти к более безопасной сети.

140
ответ дан Braden Best 18 сент. '12 в 3:56
источник поделиться

Старый вопрос, современный ответ. Используя деструктурирование объектов, 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 try-out.


Edit:

Чтобы переназначить одну и ту же переменную, используйте let:

let myObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
({ regex, ...myObject } = myObject);
console.log(myObject);
94
ответ дан Koen. 08 нояб. '16 в 21:02
источник поделиться

Другой альтернативой является использование библиотеки 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() могут использоваться аналогичным образом.

68
ответ дан Thaddeus Albers 24 мая '14 в 21:53
источник поделиться

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


Update: Благодаря @AgentME:

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

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

34
ответ дан Mehran Hatami 12 февр. '14 в 9:29
источник поделиться

Предположим, что у вас есть объект, который выглядит так:

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 также испортило бы вашу индексацию.

Таким образом, при удалении значений из объекта всегда сначала учитывайте, имеете ли вы дело с объектами или имеете дело с значениями массива и выбираете на основе соответствующей стратегии.

Если вы хотите поэкспериментировать с этим, вы можете использовать этот скрипт в качестве отправной точки.

30
ответ дан John Slegers 21 февр. '16 в 21:09
источник поделиться

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
29
ответ дан madox2 10 янв. '16 в 19:36
источник поделиться

удалить оператор - лучший способ сделать это.

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

var foo = {bar: 'bar'};
delete foo.bar;
console.log('bar' in foo); // Logs false, because bar was deleted from foo.
22
ответ дан Tarun Nagpal 28 апр. '15 в 8:14
источник поделиться

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

myObject = _.omit(myObject, 'regex');
20
ответ дан emil 22 янв. '16 в 5:29
источник поделиться

Эта статья очень старая, и я считаю ее очень полезной, поэтому я решил поделиться функцией 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"}
15
ответ дан talsibony 01 дек. '14 в 10:33
источник поделиться

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

например

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

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

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

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

14
ответ дан Willem 15 сент. '14 в 3:48
источник поделиться

Другое решение, использующее 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);
14
ответ дан kind user 26 марта '17 в 18:19
источник поделиться

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

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

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

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

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

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

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

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

  • Любое свойство, объявленное с let или const, не может быть удалено из области действия, в которой они были определены. Неконфигурируемые свойства не могут быть удалены. Сюда входят свойства встроенных объектов, таких как Math, Array, Object и свойства, которые создаются как неконфигурируемые с помощью методов Object.defineProperty().

Следующий фрагмент дает еще один простой пример:

var Employee = {
      age: 28,
      name: 'abc',
      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

13
ответ дан Alireza 07 апр. '17 в 19:16
источник поделиться

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

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

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

10
ответ дан zatziky 28 нояб. '16 в 18:14
источник поделиться

Попробуйте использовать следующий метод. Назначьте значение свойства Object undefined. Затем stringify объект и parse.

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

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

console.log(myObject);
10
ответ дан Mohammed Safeer 06 июля '16 в 17:51
источник поделиться

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

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: {}}}
10
ответ дан ayushgp 23 июня '16 в 12:38
источник поделиться

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

Например:

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

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

delete obj.key1

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

delete obj[key1]

Ссылка: MDN.

5
ответ дан Kalpesh Patel 07 апр. '16 в 8:46
источник поделиться

Попробуйте это

delete myObject['key'];
3
ответ дан codemirror 26 мая '17 в 9:58
источник поделиться

Рассмотрите возможность создания нового объекта без свойства "regex", поскольку исходный объект всегда может ссылаться на другие части вашей программы. Таким образом, вам следует избегать манипулирования им.

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

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

console.log(newMyObject);
3
ответ дан ideaboxer 23 окт. '17 в 13:06
источник поделиться

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"];
        }
    }
);
3
ответ дан xgqfrms-gildata 19 сент. '17 в 11:37
источник поделиться

Утверждение Дэна о том, что "удаление" происходит очень медленно, и поставленный в нем тест был усомнился. Поэтому я сам проверил тест в 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

Обратите внимание, что я специально выполнял несколько операций "удалить" в одном цикле цикла, чтобы минимизировать эффект, вызванный другими операциями.

3
ответ дан Chong Lip Phang 26 июля '17 в 10:19
источник поделиться

Удаление имущества в JavaScript

На этой странице представлено множество различных вариантов, а не потому, что большинство вариантов неверны, или потому, что ответы являются дубликатами, а потому, что соответствующий метод зависит от ситуации, в которой вы находитесь, и целей задач, которые вы и/или вы команда пытается выполнить. Чтобы ответить на ваш вопрос однозначно, нужно знать:

  1. Версия ECMAScript, на которую вы нацеливаетесь
  2. Диапазон типов объектов, которые вы хотите удалить, и типы имен свойств, которые вам нужно упускать (только строки) Символы? Слабые ссылки, сопоставленные с произвольными объектами? Все это были типы указателей свойств в JavaScript уже много лет )
  3. Этимы/шаблоны программирования, которые вы и ваша команда используете. Поддерживаете ли вы функциональные подходы, а мутация - в вашей команде, или вы используете дикие западные мутативные объектно-ориентированные методы?
  4. Вы хотите добиться этого в чистом JavaScript или хотите ли вы использовать стороннюю библиотеку?

После ответа на эти четыре вопроса в 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 & array в дополнение к строкам и работает в каждой версии JavaScript, за исключением самой первой версии. Однако это мутация, которая нарушает некоторые принципы программирования и имеет последствия для производительности. Это также может привести к неперехваченным исключениям при использовании в неконфигурируемых свойствах в строгом режиме.

Исключение свойств строки на основе Rest

Эта категория предназначена для работы с экземплярами простого объекта или массива в новых вариантах 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"
3
ответ дан james_womack 14 дек. '17 в 5:35
источник поделиться

Здравствуйте, Вы можете попробовать этот простой вид

var obj = [];

obj.key1 = {name: "John", room: 1234};
obj.key2 = {name: "Jim", room: 1234};

delete(obj.key1);
3
ответ дан Dhaval Gohel 26 мая '17 в 12:28
источник поделиться

Использование ES6:

(Оператор Destructuring + Spread)

    const myObject = {
      regex: "^http://.*",
      b: 2,
      c: 3
    };
    const { regex, ...noRegex } = myObject;
    console.log(noRegex); // => { b: 2, c: 3 }
2
ответ дан Srinivas 23 июля '18 в 18:52
источник поделиться

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

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

console.log(myObject)
console.log(regex)
console.log(other)
2
ответ дан xiang 06 февр. '18 в 7:28
источник поделиться

вы можете использовать оператор delete, как показано ниже.

 var multiverse = {
        earth1: "Silver Age",
        earth2: "Golden Age"
    };

delete multiverse.earth2;//will return true if it finds 

// Outputs: { earth1: "Silver Age" }
console.log(multiverse);

Оператор delete также имеет return value. Если ему удастся удалить свойство, оно вернет true. Если ему не удастся удалить свойство, потому что свойство невосстанавливаемо, оно будет return false, или если в строгом режиме оно выдает ошибку.

1
ответ дан MANISH MOHAN 13 окт. '17 в 12:40
источник поделиться

@johnstock, мы также можем использовать концепцию прототипирования JavaScript, чтобы добавить метод к объектам для удаления любого переданного ключа, доступного в вызывающем объекте.

Выше ответы приветствуются.

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

// 1st and direct way 
delete myObject.regex;  // delete myObject["regex"]
console.log(myObject); // { ircEvent: 'PRIVMSG', method: 'newURI' }

 // 2 way -  by using the concept of JavaScript prototyping concept
Object.prototype.removeFromObjectByKey = function(key) {
     // If key exists, remove it and return true
     if(this[key] !== undefined) {
           delete this[key]
           return true;
     }
     // Else return false
     return false;
}

var isRemoved = 
myObject.removeFromObjectByKey('method')
console.log(myObject)  // { ircEvent: 'PRIVMSG' }

// More examples
var obj = { a: 45, b: 56, c: 67}
console.log(obj) // { a: 45, b: 56, c: 67 }

// Remove key 'a' from obj
isRemoved = obj.removeFromObjectByKey('a')
console.log(isRemoved); //true
console.log(obj); // { b: 56, c: 67 }

// Remove key 'd' from obj which doesn't exist
var isRemoved = obj.removeFromObjectByKey('d')
console.log(isRemoved); // false
console.log(obj); // { b: 56, c: 67 }
1
ответ дан hygull 24 мая '18 в 21:42
источник поделиться

Использование lodash

import omit from 'lodash/omit';

const prevObject = {test: false, test2: true};
// Removes test2 key from previous object
const nextObject = omit(prevObject, 'test2');

Использование Ramda

R.omit(['a', 'd'], {a: 1, b: 2, c: 3, d: 4}); //=> {b: 2, c: 3}
1
ответ дан johndavedecano 14 сент. '17 в 17:14
источник поделиться
  • 1
  • 2

Другие вопросы по меткам