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

Скажімо, я створюю об'єкт наступним чином:

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

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

 var myObject = { "ircEvent": "PRIVMSG", "method": "newURI" }; 
5276
16 окт. заданий johnstok 16 Жовтня. 2008-10-16 13:57 '08 о 13:57 2008-10-16 13:57
@ 37 відповідей
  • 1
  • 2

Ось так:

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

Demo

kangax написав неймовірно докладне повідомлення в блозі про заяву delete в своєму блозі, Розуміння видалення .  Настійно рекомендується. 

7292
16 окт. відповідь дан nickf 16 Жовтня. 2008-10-16 13:58 '08 о 13:58 2008-10-16 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 .

border=0
  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. *'); too  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. *'); 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 ); }); use "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 ); }); use "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 browser 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 its entries have the 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 all its entries have the 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 .

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

770
12 февр. відповідь дан Dan 12 февр. 2014-02-12 20:48 '14 о 20:48 2014-02-12 20:48

215
16 окт. відповідь дан redsquare 16 Жовтня. 2008-10-16 14:03 '08 о 14:03 2008-10-16 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];  

Як ви можете бачити, 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();  

Так, це безумовно не те, що ви хотіли.

Тепер ви можете зберегти другий итератор, наприклад 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 code made my browser segfault 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]  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 году.). Чем раньше все откажутся от поддержки этих старых/эзотерических браузеров, тем скорее поставщики браузеров будут действительно следовать веб-стандарту и охватывают новые технологии, и чем скорее мы сможем перейти к более безопасной сети.

164
ответ дан Braden Best 18 сент. '12 в 3:56 2012-09-18 03:56

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

 const { a, ...rest } = { a: 1, b: 2, c: 3 };