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

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

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

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

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

30 ответов


такой:

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 user kangax написал невероятно глубокий пост в блоге о delete заявление в своем блоге, понимание удалить. Настоятельно рекомендуется.


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

посмотреть benchmark.

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

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

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

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

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

это удаляет ключ из hashmap.

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

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

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

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

используя этот метод, не все!--79-->способы определения наличия имущества будет работать, как ожидалось.

этот код:

object.field === undefined

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

тесты

подводя итог, различия все о способах определения наличия собственности, и о 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\'s 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 to 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 слотов будут установлены только в 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
            /********************************************/
            /****/ 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. Таким образом, даже если вы восстановите полиморфный массив до неполиморфного, он все равно будет сохранен браузером как полиморфный массив.

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

но как аналогия с наркотической поездкой соотносится с 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). Когда целое число понижается до double, его нельзя возвратить к целому числу.
  • при использовании массива / переменной, введенной в строковый примитив, используйте "" как пустое значение.
  • при использовании символа Подождите, почему вы используете символ?!?! Символы плохи для исполнения. Все запрограммированное на использование символов может быть перепрограммировано, чтобы не использовать символы, в результате чего быстрее код без символов. Символы - это просто супер неэффективный мета-сахар.
  • при использовании чего-либо еще используйте null.

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


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

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

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


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


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

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

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

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

массив эквивалентно

не delete из массива. Использовать 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], etc.)

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

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

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

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

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

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

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

Ладно, давайте просто скажем, что вы пытаетесь сохранить память по просьбе один пользователь, который запускает мини-компьютер PDP-11 с 1960-х годов под управлением UNIX и написал свой собственный браузер на основе Elinks, совместимый с 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 вопрос, и вы все еще должны угодить этому тролль 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

к счастью, массивы do есть специализированный метод удаления индексов и перераспределения памяти: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. Ура! (я бы все равно отругал его...)

массив.прототип.соединение vs Матрица.прототип.ломтик

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

массив.прототип.splice (start, n)

.splice() изменяет массив и возвращает удаленные индексы. Массив разрезается, начиная с индекса,start и n элементы вырезаны. Если N не указано, весь массив после 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]

массив.прототип.фрагмент(начало, конец)

.slice() является неразрушающим и возвращает новый массив, содержащий указанные показатели от start to 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 просто исключается из среза. Индексы в скобках указывают, что будет нарезано. В любом случае, поведение не является интуитивным, и оно обязательно вызовет справедливую долю ошибок off-by-one, поэтому вам может оказаться полезным сделать функцию-оболочку более близкой к эмуляции поведение .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, есть ваш polyfill. Тем не менее, я настоятельно рекомендую использовать мои is_array() функция, поскольку продолжение поддержки старых версий JavaScript означает продолжение поддержки старых браузеров, которые их реализуют, что означает поощрение использования небезопасного программного обеспечения и ставит пользователей под угрозу вредоносного ПО. Поэтому, пожалуйста, используйте Array.isArray(). Использовать let и const. Используйте новые функции, которые добавляются в язык. не использовать префиксы поставщиков. удалить что IE polyfill дерьмо с вашего сайта. Удалите этот XHTML <!CDATA[[... дерьмо, тоже--мы переехали в HTML5 еще в 2014 году. Чем скорее все откажутся от поддержки этих старых / эзотерических браузеров, тем скорее поставщики браузеров действительно будут следовать веб-стандарту и примут новую технологию, и тем скорее мы сможем перейти к более безопасной сети.


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

Другой альтернативой является использование подчеркивания.js библиотека.

отметим, что _.pick() и _.omit() оба возвращают копию объекта и непосредственно не изменяют исходный объект. Назначение результата исходному объекту должно сделать трюк (не показано).

ссылки: ссылке _.pick (object, *keys)

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

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

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

ссылки: ссылке _.опустить (объект, * ключи)

верните копию объекта, отфильтрованную, чтобы опустить черный список ключей (или массив ключей).

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

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

для массивов, _.filter() и _.reject() может использоваться аналогичным образом.


термин, который вы использовали в своем названии вопроса 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 заявление, и если вы do:

delete regex; //False

результат будет false, что означает, что ваш оператор delete не был выполнен, как вы ожидали. Но если вы не создали эту переменную раньше, и у вас было только myOtherObject["regex"] в качестве последней существующей ссылки вы могли бы сделать это, просто удалив ее, как:

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

другими словами, объект JavaScript будет убит, как только в вашем коде не останется ссылки на это объект.


обновление: Благодаря @AgentME:

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

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


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

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

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

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


ECMAScript 2015 (или ES6) поставляется со встроенным отражает


на оператор delete Это лучший способ, чтобы сделать это.

живой пример:

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

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

myObject = _.omit(myObject, 'regex');

этот пост очень старый, и я нахожу его очень полезным, поэтому я решил поделиться функцией 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"}

другое решение, используя 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);

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

Е. Г

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

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

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

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


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

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

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

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

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

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

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

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

  • любое свойство, объявленное с помощью let или const, не может быть удалено из области, в которой они были определены. Не настраиваемые свойства не могут быть удалены. Этот включает свойства встроенных объектов, таких как Math, Array, Object и properties, которые создаются как не настраиваемые с помощью таких методов, как 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


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

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

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

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

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

console.log(myObject);

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

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

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


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

например:

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

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

delete obj.key1

или вы также можете использовать array-like notation:

delete obj[key1]

Ref:MDN.


Распространение Синтаксис (ES6)

кому это нужно...

чтобы завершить ответ @Koen в этом потоке, если вы хотите удалить динамическую переменную с помощью синтаксиса распространения, вы можете сделать это так:

const key = 'a';

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

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

* foo будет новой переменной со значением a (который 1).


попробуй такое

delete myObject['key'];

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

var obj = [];

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

delete(obj.key1);

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

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


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

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

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

console.log(newMyObject);

Удаление свойств в JavaScript

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

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

после того, как эти четыре запроса были даны ответы, есть по существу четыре категории "Удаление свойств" в JavaScript, чтобы выбрать из Для достижения ваших целей. Они:

объект мутационной удаление собственность, небезопасных

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

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

эта категория является самой старой, самой простой и наиболее широко поддерживаемой категорией удаления собственности. Он поддерживает Symbol & array индексирует в дополнение к строкам и работает в каждой версии JavaScript, за исключением самого первого выпуска. Однако это мутация, которая нарушает некоторые принципы программирования и имеет последствия для производительности. Это также может привести к неперехваченные исключения при использовании на не настраиваемые свойства в строгом режиме.

REST-based string пропуск свойства

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

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

объект мутационной удаление собственность, сейф

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

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

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

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

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

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

библиотечное свойство пропуск

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

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"

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

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

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

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

(Destructuring + Spread operator)

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

очень просто:

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

delete myObject.regex;

использование 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}