javascript - удаление - свойства объекта




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

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

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

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

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

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


UPDATE :
Существует несколько способов удаления свойства из объекта.
У каждого есть свои плюсы и минусы ( проверьте это сравнение производительности ):

developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Читаемый и короткий, однако это может быть не лучший выбор, если вы работаете с большим количеством объектов, так как его производительность не оптимизирована.

delete obj[key];


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

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


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

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

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"];
        }
    }
);


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

Посмотрите на benchmark .

Удалить - единственный верный способ удаления свойств объекта без каких-либо остатков, но он работает ~ в 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\'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 для 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 .

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


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

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

Ссылка: link _.pick (объект, * ключи)

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

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

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

Ссылка: link _.omit (объект, * ключи)

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

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

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

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


Попробуй это

delete myObject['key'];

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

Редактировать:

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

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

Обновление 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 - что является законно странным - это поведение не должно удивлять, поскольку delete - это унарный оператор, такой как typeof , который вкручен в язык и не должен заботиться о типе объекта, на котором он используется, тогда как Array является подклассом Object с методами, специально разработанными для работы с массивами. Таким образом, нет никакой веской причины для delete чтобы иметь специальный случай, приготовленный для повторного смещения массива, поскольку это просто замедлит работу с ненужной работой. Оглядываясь назад, мои ожидания были нереалистичными.

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

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

Который является ужасным оправданием для избавления от null s- 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 проблему, и вам все равно понравится этот пользователь 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() поведения .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 году.). Чем раньше все откажутся от поддержки этих старых / эзотерических браузеров, тем скорее поставщики браузеров будут действительно следовать веб-стандарту и охватывают новые технологии, и чем скорее мы сможем перейти к более безопасной сети.


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

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

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

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

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

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

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

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

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

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


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

var obj = [];

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

delete(obj.key1);

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

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

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


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

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

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


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

Например:

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

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

delete obj.key1

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

delete obj[key1]

Ссылка: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… .


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


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

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

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



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

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

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

console.log(newMyObject);


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

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





object-properties