Object.values() and Object.entries()
Object.values() Method
Object.values() is a static method introduced in ES8 that returns an array of a given object's own enumerable property values. Unlike Object.keys(), which returns property names, it directly returns an array composed of property values.
const person = {
name: '张三',
age: 25,
gender: 'male'
};
const values = Object.values(person);
console.log(values); // ['张三', 25, 'male']
This method is particularly useful when working with objects, especially when only the property values are needed and the keys are irrelevant. It follows the same order as the for...in
loop but does not traverse properties on the prototype chain.
For array objects, Object.values() returns the array elements:
const arr = ['a', 'b', 'c'];
console.log(Object.values(arr)); // ['a', 'b', 'c']
For strings, it returns an array of characters:
const str = 'hello';
console.log(Object.values(str)); // ['h', 'e', 'l', 'l', 'o']
Object.entries() Method
The Object.entries() method returns an array of a given object's own enumerable property key-value pairs, where each pair is an array containing the key and value.
const person = {
name: '李四',
age: 30,
profession: '工程师'
};
const entries = Object.entries(person);
console.log(entries);
// [
// ['name', '李四'],
// ['age', 30],
// ['profession', '工程师']
// ]
This method is particularly suitable for converting objects into Maps:
const map = new Map(Object.entries(person));
console.log(map.get('name')); // '李四'
When working with objects, Object.entries() pairs perfectly with array iteration methods:
Object.entries(person).forEach(([key, value]) => {
console.log(`${key}: ${value}`);
});
// name: 李四
// age: 30
// profession: 工程师
Practical Use Cases
Data Transformation
These methods are highly useful for data transformation. For example, converting an object into an array containing only specific values:
const products = {
p1: { name: '手机', price: 2999 },
p2: { name: '笔记本', price: 5999 },
p3: { name: '平板', price: 3999 }
};
// Get all prices
const prices = Object.values(products).map(p => p.price);
console.log(prices); // [2999, 5999, 3999]
Object Filtering
Combining these methods with array operations makes object filtering straightforward:
const filtered = Object.entries(products)
.filter(([_, product]) => product.price > 3000)
.reduce((obj, [key, val]) => {
obj[key] = val;
return obj;
}, {});
console.log(filtered);
// {
// p2: { name: '笔记本', price: 5999 },
// p3: { name: '平板', price: 3999 }
// }
Form Data Processing
They are especially convenient for handling form data:
const formData = {
username: 'user123',
password: 'secret',
remember: true
};
// Convert to URL query string
const queryString = Object.entries(formData)
.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
.join('&');
console.log(queryString); // "username=user123&password=secret&remember=true"
Comparison with Similar Methods
Comparison with Object.keys()
Object.keys() returns only the keys, Object.values() returns only the values, and Object.entries() returns key-value pairs:
const obj = { a: 1, b: 2, c: 3 };
console.log(Object.keys(obj)); // ['a', 'b', 'c']
console.log(Object.values(obj)); // [1, 2, 3]
console.log(Object.entries(obj)); // [['a', 1], ['b', 2], ['c', 3]]
Comparison with for...in Loop
The for...in
loop traverses enumerable properties on the prototype chain, whereas Object methods do not:
function Person() {
this.name = '王五';
}
Person.prototype.age = 20;
const p = new Person();
// for...in includes prototype properties
for (const key in p) {
console.log(key); // Outputs 'name' and 'age'
}
// Object methods include only own properties
console.log(Object.keys(p)); // ['name']
console.log(Object.values(p)); // ['王五']
console.log(Object.entries(p)); // [['name', '王五']]
Handling Edge Cases
Non-Object Parameters
When non-object parameters are passed, these methods first convert them into objects:
// Numbers and booleans are converted to empty objects
console.log(Object.values(123)); // []
console.log(Object.entries(true)); // []
// null and undefined throw TypeError
try {
Object.values(null);
} catch (e) {
console.log(e); // TypeError: Cannot convert undefined or null to object
}
Symbol Properties
By default, Object.values() and Object.entries() do not include Symbol properties:
const sym = Symbol('description');
const obj = {
[sym]: 'symbol value',
regular: 'regular value'
};
console.log(Object.values(obj)); // ['regular value']
console.log(Object.entries(obj)); // [['regular', 'regular value']]
To retrieve Symbol properties, use Reflect.ownKeys()
or Object.getOwnPropertySymbols()
.
Performance Considerations
When working with large objects, these methods create new arrays, which may incur memory overhead. In performance-sensitive scenarios, using a for...in
loop directly might be more efficient:
// More efficient approach
const values = [];
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
values.push(obj[key]);
}
}
However, in most cases, the difference is negligible, and code readability and simplicity are more important.
Integration with Other ES6+ Features
Combining with Destructuring Assignment
const config = {
apiUrl: 'https://api.example.com',
timeout: 5000,
retries: 3
};
for (const [key, value] of Object.entries(config)) {
console.log(`Config ${key}: ${value}`);
}
Combining with Spread Operator
const defaults = { color: 'red', size: 'medium' };
const userSettings = { size: 'large' };
const combined = {
...defaults,
...userSettings
};
console.log(Object.entries(combined));
// [['color', 'red'], ['size', 'large']]
Combining with Array.from()
const obj = { a: 1, b: 2, c: 3 };
const mapped = Array.from(Object.entries(obj), ([key, value]) => ({
key,
double: value * 2
}));
console.log(mapped);
// [
// { key: 'a', double: 2 },
// { key: 'b', double: 4 },
// { key: 'c', double: 6 }
// ]
Usage in React
In React, these methods can simplify props handling:
function UserProfile(props) {
return (
<div>
{Object.entries(props).map(([key, value]) => (
<p key={key}>
<strong>{key}:</strong> {value}
</p>
))}
</div>
);
}
// Usage
<UserProfile name="赵六" age={28} occupation="设计师" />
Usage in Vue
In Vue, they can conveniently handle reactive objects:
const vm = new Vue({
data() {
return {
user: {
name: '钱七',
age: 35,
job: '经理'
}
};
},
computed: {
userEntries() {
return Object.entries(this.user);
}
}
});
// In the template, it can be used directly:
// <div v-for="[key, value] in userEntries" :key="key">
// {{ key }}: {{ value }}
// </div>
Usage in Node.js
When handling HTTP requests, they can simplify request header processing:
const http = require('http');
http.createServer((req, res) => {
// Convert request headers to an array
const headers = Object.entries(req.headers);
res.writeHead(200, { 'Content-Type': 'text/plain' });
headers.forEach(([name, value]) => {
res.write(`${name}: ${value}\n`);
});
res.end();
}).listen(3000);
Browser Compatibility Considerations
While modern browsers support these methods, older environments may require polyfills:
// Object.values polyfill
if (!Object.values) {
Object.values = function(obj) {
return Object.keys(obj).map(key => obj[key]);
};
}
// Object.entries polyfill
if (!Object.entries) {
Object.entries = function(obj) {
return Object.keys(obj).map(key => [key, obj[key]]);
};
}
Alternatively, use tools like Babel to transpile the code, ensuring it runs correctly in target environments.
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn
下一篇:尾调用优化