Альтернативна версія Object.values ​​()


79

Шукаю альтернативну версію Object.values()функції.
Як описано тут, функція не підтримується в Internet Explorer.

При виконанні наступного прикладу коду:

var obj = { foo: 'bar', baz: 42 };
console.log(Object.values(obj)); // ['bar', 42]

Він працює як у Firefox, так і в Chrome, але в IE11 видає таку помилку:

Об'єкт не підтримує властивості або "значення" методу

Тут ви можете його перевірити: Скрипка .

Отже, що було б швидким виправленням?

Відповіді:


179

Ви можете отримати масив ключів за допомогою, Object.keys()а потім використовувати map()для отримання значень.

var obj = { foo: 'bar', baz: 42 };
var values = Object.keys(obj).map(function(e) {
  return obj[e]
})

console.log(values)

За допомогою ES6 ви можете написати це в один рядок за допомогою стрілочних функцій.

var values = Object.keys(obj).map(e => obj[e])

2
Дякую! Для мого кутового коду 5 я змінився objectValues = Object.values;наobjectValues = ((obj) => { return Object.keys(obj).map(e => obj[e]); });
Джефф

@Jeff, чому ти не дивишся на кутові поліфіли?
Сакшам,

angular8 polyfill.ts:import 'core-js/es/object/values';
wutzebaer

21

Object.values ​​() є частиною специфікації ES8 (червень 2017 р.). Використовуючи Cordova, я зрозумів, що Android 5.0 Webview його не підтримує. Отже, я зробив наступне, створивши функцію polyfill, лише якщо ця функція не підтримується:

if (!Object.values) Object.values = o=>Object.keys(o).map(k=>o[k]);

16

Оскільки Object є ( не такою ) недавньою реалізацією, якщо ви хочете підтримувати всі браузери (AKA IE8 і нижче), то вам потрібно створити власну функцію:

function objectValues(obj) {
    var res = [];
    for (var i in obj) {
        if (Object.prototype.hasOwnProperty.call(obj, i)) {
            res.push(obj[i]);
        }
    }
    return res;
}

PS: Щойно помітив ecmascript-6тег. До речі, я зберігаю цю відповідь тут, на випадок, якщо комусь вона потрібна.


9

Якщо ви вже використовуєте core-js (наприклад, за допомогою Angular), ви можете просто імпортувати відповідний polyfill:

   import 'core-js/es7/object';

Залежно від того, яку версію Angular ви використовуєте, можливо, вам доведеться змінити імпорт: import 'core-js / es / object';
Марк Томпсон

7

Ви можете використовувати поліфіл:

const valuesPolyfill = function values (object) {
  return Object.keys(object).map(key => object[key]);
};

const values = Object.values || valuesPolyfill;

console.log(values({ a: 1, b: 2, c: 3 }));


4

Для людей, які використовують UnderscoreJS , ви можете отримати значення об’єктів, використовуючи _.values:

var obj = { foo: 'bar', baz: 42 };
console.log(_.values(obj)); // ['bar', 42]

2

var x = {Name: 'John', Age: 30, City: 'Bangalore'};
 
Object.prototype.values = function(obj) {
                                var res = [];
    for (var i in obj) {
        if (obj.hasOwnProperty(i)) {
            res.push(obj[i]);
        }
    }
    return res;
};
 
document.getElementById("tag").innerHTML = Object.values(x)
<p id="tag"></p>


2
Це не метод-прототип.
Берги

0

Я знаю, що це стара тема. Я грав навколо і просто хочу додати ще одну реалізацію. Це просто версія карти з самою картою, реалізованою із зменшенням:

let obj = { foo: 'bar', baz: 42 };

const valueArray = Object.keys(obj).reduce((acc, key) => {
  acc.push(obj[key]);
  return acc;
}, []);

console.log(valueArray);

Це робить свою роботу, але це щось мене турбує. Функція редуктора використовує obj, і obj в неї не вводили . Ми повинні уникати глобальних змінних всередині функцій і робити наші функції більш перевіряемыми . Тому я віддаю перевагу цій версії з помічником функції редуктора, який приймає obj як параметр і повертає фактичну функцію редуктора . Це стає:

let obj = { foo: 'bar', baz: 42 };

// reducer function helper take obj and return the actual reducer function
let reducerFuncHelper= obj => (acc, key) => {
  acc.push(obj[key]);
  return acc;
}
//much better
const valueArray = Object.keys(obj).reduce(reducerFuncHelper(obj), []);
console.log(valueArray);


0

Найкращий спосіб - це замінити його методом значень ramda:

import * as R from 'ramda';

const obj = { foo: 'bar', test: 10 };

console.log(R.values(obj)) // ['bar', 10]


-1

Оскільки я не знайшов відповіді на свої потреби:

var obj = { foo: 'bar', baz: 42 };


console.log(obj[Object.keys(obj)[0]]) // bar

console.log(obj[Object.keys(obj)[1]])  // 42

Використовуючи можливість об’єктів адресувати їх по буквалу.


Не відповідь мій друже
fluidguid

@fluidguid: дякую за коментар, це моя перша відповідь, я повинен навчитися. Чому? Я думав, що проблема полягає в отриманні значень об’єкта в IE. Отже, з тобто простим "за" у мене є. що не так?
Frank34

-1

Ви можете отримати масив ключів за допомогою Object.keys (). Це також буде працювати в IE. Object.values ​​() взагалі не потрібен для отримання значень, оскільки ми можемо використовувати ключі, отримані з Object.keys (), щоб отримати значення, як показано нижче:

var obj = { foo: 'bar', baz: 42 };
var keyArray = Object.keys(obj);
for(var i = 0; i < keyArray.length; i++)
    console.log(obj[keyArray[i]]); 

1
Ви дійсно вважаєте, що це хороше рішення для Object.values ​​????
човновий кодер
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.