Lodash和Underscore是极好的js工具库,在前端开发中得到了广泛的使用。然而如果你想减少项目依赖,并且所支持的浏览器非常先进的话(IE8之前的除外),你会发现在ES5与ES6中已经提供了非常多的原生方法,你可以不是用Lodash或者Underscore.
Array
Collection*
1. _.each
1. _.every
1. _.filter
1. _.groupBy
1. _.includes
1. _.map
1. .minBy and .maxBy
1. _.pluck
1. _.range
1. _.reduce
1. _.reduceRight
1. _.size
1. _.some
Function
Lang
Object
String
上述目录标记为*的表示只有数组提供了等同的原生方法。如果你想在对象上使用这些方法只能选择Lodash/Underscore.
移除数组中所有非真的数,并返回一个新的数组。
// Underscore/Lodash
_.compact([0, 1, false, 2, '', 3]);
// Native
[0, 1, false, 2, '', 3].filter(v => v)
✔ | 1.5 ✔ | 9 ✔ | ✔ | ✔ |
连接其他的数组或对象,并返回一个新的数组
// Underscore/Lodash
var array = [1]
var other = _.concat(array, 2, [3], [[4]])
console.log(other)
// output: [1, 2, 3, [4]]
// Native
var array = [1]
var other = array.concat(2, [3], [[4]])
console.log(other)
// output: [1, 2, 3, [4]]
1.0 ✔ | 1.0 ✔ | 5.5 ✔ | ✔ | ✔ |
填充数组,从某个位置开始到某个位置结束,但不包括结束位。
// Underscore/Lodash
var array = [1, 2, 3]
_.fill(array, 'a')
console.log(array)
// output: ['a', 'a', 'a']
_.fill(Array(3), 2)
// output: [2, 2, 2]
_.fill([4, 6, 8, 10], '*', 1, 3)
// output: [4, '*', '*', 10]
// Native
var array = [1, 2, 3]
array.fill('a')
console.log(array)
// output: ['a', 'a', 'a']
Array(3).fill(2)
// output: [2, 2, 2]
[4, 6, 8, 10].fill('*', 1, 3)
// output: [4, '*', '*', 10]
45.0 ✔ | 31.0 ✔ | Not supported | Not supported | 7.1 ✔ |
返回数组中第一个满足条件的值,否则返回undefined
// Underscore/Lodash
var users = [
{ 'user': 'barney', 'age': 36, 'active': true },
{ 'user': 'fred', 'age': 40, 'active': false },
{ 'user': 'pebbles', 'age': 1, 'active': true }
]
_.find(users, function (o) { return o.age < 40; })
// output: object for 'barney'
// Native
var users = [
{ 'user': 'barney', 'age': 36, 'active': true },
{ 'user': 'fred', 'age': 40, 'active': false },
{ 'user': 'pebbles', 'age': 1, 'active': true }
]
users.find(function (o) { return o.age < 40; })
// output: object for 'barney'
45.0 ✔ | 25.0 ✔ | Not supported | Not supported | 7.1 ✔ |
返回数组中第一个满足条件的位置,如果未找到,则返回-1.
// Underscore/Lodash
var users = [
{ 'user': 'barney', 'age': 36, 'active': true },
{ 'user': 'fred', 'age': 40, 'active': false },
{ 'user': 'pebbles', 'age': 1, 'active': true }
]
var index = _.findIndex(users, function (o) { return o.age >= 40; })
console.log(index)
// output: 1
// Native
var users = [
{ 'user': 'barney', 'age': 36, 'active': true },
{ 'user': 'fred', 'age': 40, 'active': false },
{ 'user': 'pebbles', 'age': 1, 'active': true }
]
var index = users.findIndex(function (o) { return o.age >= 40; })
console.log(index)
// output: 1
45.0 ✔ | 25.0 ✔ | Not supported | Not supported | 7.1 ✔ |
返回数组中第一个或前几个元素.
// Underscore/Lodash
_.first([1, 2, 3, 4, 5]);
// => 1
_.first([1, 2, 3, 4, 5], 2);
// => [1, 2]
// Native
[1, 2, 3, 4, 5][0];
// => 1
[1, 2, 3, 4, 5].slice(0, 2);
// => [1, 2]
✔ | ✔ | ✔ | ✔ | ✔ |
降低一级数组嵌套。
// Underscore/Lodash
_.flatten([1, [2, [3, [4]], 5]]);
// => [1, 2, [3, [4]], 5]
// Native
const flatten = [1, [2, [3, [4]], 5]].reduce( (a, b) => a.concat(b), [])
// => [1, 2, [3, [4]], 5]
46.0 ✔ | 16.0 ✔ | Not supported | Not supported | 7.1 ✔ |
去除数组中所有其他数组.
// Underscore/Lodash
_.flattenDeep([1, [2, [3, [4]], 5]]);
// => [1, 2, 3, 4, 5]
// Native
const flattenDeep = (arr) => Array.isArray(arr)
? arr.reduce( (a, b) => [...flattenDeep(a), ...flattenDeep(b)] , [])
: [arr]
flattenDeep([1, [[2], [3, [4]], 5]])
// => [1, 2, 3, 4, 5]
46.0 ✔ | 16.0 ✔ | Not supported | Not supported | 7.1 ✔ |
获得数组中的第一个元素;获得数组中除第一个元素之外的其他元素
const array = [1, 2, 3]
// Underscore: _.first, _.head, _.take
// Lodash: _.first, _.head
_.head(array)
// output: 1
// Underscore: _.rest, _.tail, _.drop
// Lodash: _.tail
_.tail(array)
// output: [2, 3]
// Native
const [ head, ...tail ] = array
console.log(head)
// output: 1
console.log(tail)
// output [2, 3]
49 ✔ | 34 ✔ | Not Supported | Not Supported | ✔ |
返回在数组中可以找到一个给定元素的第一个索引,如果不存在,则返回-1.
var array = [2, 9, 9]
var result = _.indexOf(array, 2)
console.log(result)
// output: 0
// Native
var array = [2, 9, 9]
var result = array.indexOf(2)
console.log(result)
// output: 0
✔ | 1.5 ✔ | 9 ✔ | ✔ | ✔ |
使用给定的分隔符连接数组中的所有元素
// Lodash
var result = _.join(['one', 'two', 'three'], '--')
console.log(result)
// output: 'one--two--three'
// Native
var result = ['one', 'two', 'three'].join('--')
console.log(result)
// output: 'one--two--three'
1.0 ✔ | 1.0 ✔ | 5.5 ✔ | ✔ | ✔ |
返回数组中最后的一到多个元素.
// Underscore/Lodash
const numbers = [1, 2, 3, 4, 5];
_.last(numbers);
// => 5
_.last(numbers, 2);
// => [4, 5]
// Native
const numbers = [1, 2, 3, 4, 5];
numbers[numbers.length - 1];
// => 5
//or
numbers.slice(-1)[0];
// => 5
numbers.slice(-2);
// => [4, 5]
✔ | ✔ | ✔ | ✔ | ✔ |
返回指定元素在数组中的最后一个的索引,如果不存在则返回 -1.
// Underscore/Lodash
var array = [2, 9, 9, 4, 3, 6]
var result = _.lastIndexOf(array, 9)
console.log(result)
// output: 2
// Native
var array = [2, 9, 9, 4, 3, 6]
var result = array.lastIndexOf(9)
console.log(result)
// output: 2
✔ | ✔ | 9 ✔ | ✔ | ✔ |
使数组中元素逆序.
// Lodash
var array = [1, 2, 3]
console.log(_.reverse(array))
// output: [3, 2, 1]
// Native
var array = [1, 2, 3]
console.log(array.reverse())
// output: [3, 2, 1]
1.0 ✔ | 1.0 ✔ | 5.5 ✔ | ✔ | ✔ |
返回去除给定元素的数组
// Lodash
var array = [1, 2, 3]
console.log(_.without(array, 2))
// output: [1, 3]
// Native
var array = [1, 2, 3]
console.log(array.filter(function(value) {
return value !== 2;
}));
// output: [1, 3]
1.0 ✔ | 1.5 ✔ | 9 ✔ | ✔ | ✔ |
返回给定范围的一个浅拷贝数组.
// Lodash
var array = [1, 2, 3, 4]
console.log(_.slice(array, 1, 3))
// output: [2, 3]
// Native
var array = [1, 2, 3, 4]
console.log(array.slice(1, 3));
// output: [2, 3]
✔ | ✔ | ✔ | ✔ | ✔ |
判断一个对象是不是数组.
// Lodash
var array = []
console.log(_.isArray(array))
// output: true
// Native
var array = []
console.log(Array.isArray(array));
// output: true
#### 浏览器支持
5 ✔ | 4 ✔ | 9 ✔ | 10.5 ✔ | 5 ✔ |
迭代循环数组中的每个元素。
// Underscore/Lodash
_.each([1, 2, 3], function (value, index) {
console.log(value)
})
// output: 1 2 3
// Native
[1, 2, 3].forEach(function (value, index) {
console.log(value)
})
// output: 1 2 3
✔ | 1.5 ✔ | 9 ✔ | ✔ | ✔ |
测试数组的所有元素是否都通过了指定函数的测试.
// Underscore/Lodash
function isLargerThanTen (element, index, array) {
return element >= 10
}
var array = [10, 20, 30]
var result = _.every(array, isLargerThanTen)
console.log(result)
// output: true
// Native
function isLargerThanTen (element, index, array) {
return element >= 10
}
var array = [10, 20, 30]
var result = array.every(isLargerThanTen)
console.log(result)
// output: true
✔ | 1.5 ✔ | 9 ✔ | ✔ | ✔ |
创建一个新数组, 其包含通过所提供函数实现的测试的所有元素.
function isBigEnough (value) {
return value >= 10
}
var array = [12, 5, 8, 130, 44]
var filtered = _.filter(array, isBigEnough)
console.log(filtered)
// output: [12, 130, 44]
// Native
function isBigEnough (value) {
return value >= 10
}
var array = [12, 5, 8, 130, 44]
var filtered = array.filter(isBigEnough)
console.log(filtered)
// output: [12, 130, 44]
✔ | 1.5 ✔ | 9 ✔ | ✔ | ✔ |
根据关键字或者函数分组数组中的所有元素.
// Underscore/Lodash
var grouped = _.groupBy(['one', 'two', 'three'], 'length')
console.log(grouped)
// output: {3: ["one", "two"], 5: ["three"]}
// Native
var grouped = ['one', 'two', 'three'].reduce((r, v, i, a, k = v.length) => ((r[k] || (r[k] = [])).push(v), r), {})
console.log(grouped)
// output: {3: ["one", "two"], 5: ["three"]}
// Underscore/Lodash
var grouped = _.groupBy([1.3, 2.1, 2.4], num => Math.floor(num))
console.log(grouped)
// output: {1: [1.3], 2: [2.1, 2.4]}
// Native
var grouped = [1.3, 2.1, 2.4].reduce((r, v, i, a, k = Math.floor(v)) => ((r[k] || (r[k] = [])).push(v), r), {})
console.log(grouped)
// output: {1: [1.3], 2: [2.1, 2.4]}
✔ | 3.0 ✔ | 9 ✔ | 10.5 ✔ | 4.0 ✔ |
检测数组中是否存在某个元素.
var array = [1, 2, 3]
// Underscore/Lodash - also called _.contains
_.includes(array, 1)
// output: true
// Native
var array = [1, 2, 3]
array.includes(1)
// output: true
// Native (does not use same value zero)
var array = [1, 2, 3]
array.indexOf(1) > -1
// output: true
Array.prototype.includes
47 ✔ | 43 ✔ | Not supported | 34 ✔ | 9 ✔ |
Array.prototype.indexOf
✔ | ✔ | ✔ | ✔ | ✔ |
创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果.
// Underscore/Lodash
var array1 = [1, 2, 3]
var array2 = _.map(array1, function (value, index) {
return value * 2
})
console.log(array2)
// output: [2, 4, 6]
// Native
var array1 = [1, 2, 3]
var array2 = array1.map(function (value, index) {
return value * 2
})
console.log(array2)
// output: [2, 4, 6]
获取数组中的最大或最小的值.
// Underscore/Lodash
var data = [{ value: 6 }, { value: 2 }, { value: 4 }]
var minItem = _.minBy(data, 'value')
var maxItem = _.maxBy(data, 'value')
console.log(minItem, maxItem)
// output: { value: 2 } { value: 6 }
// Native
var data = [{ value: 6 }, { value: 2 }, { value: 4 }]
var minItem = data.reduce(function(a, b) { return a.value <= b.value ? a : b }, {})
var maxItem = data.reduce(function(a, b) { return a.value >= b.value ? a : b }, {})
console.log(minItem, maxItem)
// output: { value: 2 }, { value: 6 }
// ES6
// utils
const makeSelect = (comparator) => (a, b) => comparator(a, b) ? a : b
const minByValue = makeSelect((a, b) => a.value <= b.value)
const maxByValue = makeSelect((a, b) => a.value >= b.value)
// main logic
const data = [{ value: 6 }, { value: 2 }, { value: 4 }]
const minItem = data.reduce(minByValue, {})
const maxItem = data.reduce(maxByValue, {})
console.log(minItem, maxItem)
// output: { value: 2 }, { value: 6 }
// or also more universal and little slower variant of minBy
const minBy = (collection, key) => {
// slower because need to create a lambda function for each call...
const select = (a, b) => a[key] <= b[key] ? a : b
return collection.reduce(select, {})
}
console.log(minBy(data, 'value'))
// output: { value: 2 }
✔ | 3.0 ✔ | 9 ✔ | 10.5 ✔ | 4.0 ✔ |
抽取数组中元素对象的某个属性值组成一个新数组.
// Underscore/Lodash
var array1 = [{name: "Alice"}, {name: "Bob"}, {name: "Jeremy"}]
var names = _.pluck(array1, "name")
console.log(names)
// output: ["Alice", "Bob", "Jeremy"]
// Native
var array1 = [{name: "Alice"}, {name: "Bob"}, {name: "Jeremy"}]
var names = array1.map(function(x){
return x.name
})
console.log(names)
// output: ["Alice", "Bob", "Jeremy"]
✔ | 1.5 ✔ | 9 ✔ | ✔ | ✔ |
对累加器和数组中的每个元素(从左到右)应用一个函数,将其减少为单个值.
// Underscore/Lodash
var array = [0, 1, 2, 3, 4]
var result = _.reduce(array, function (previousValue, currentValue, currentIndex, array) {
return previousValue + currentValue
})
console.log(result)
// output: 10
// Native
var array = [0, 1, 2, 3, 4]
var result = array.reduce(function (previousValue, currentValue, currentIndex, array) {
return previousValue + currentValue
})
console.log(result)
// output: 10
✔ | 3.0 ✔ | 9 ✔ | 10.5 ✔ | 4.0 ✔ |
创建一个填充好的数值数组.
// Underscore/Lodash
_.range(4) // output: [0, 1, 2, 3]
_.range(-4) // output: [0, -1, -2, -3]
_.range(1, 5) // output: [1, 2, 3, 4]
_.range(0, 20, 5) // output: [0, 5, 10, 15]
// Native ( solution with Array.from )
Array.from({length: 4}, (_, i) => i) // output: [0, 1, 2, 3]
Array.from({length: 4}, (_, i) => -i) // output: [0, -1, -2, -3]
Array.from({length: 4}, (_, i) => i + 1) // output: [1, 2, 3, 4]
Array.from({length: 4}, (_, i) => i * 5) // output: [0, 5, 10, 15]
// Native ( solution with keys() and spread )
[...Array(4).keys()] // output: [0, 1, 2, 3]
45 ✔ | 32 ✔ | Not supported | ✔ | 9.0 ✔ |
46 ✔ | 16 ✔ | Not supported | 37 ✔ | 7.1 ✔ |
接受一个函数作为累加器(accumulator)和数组的每个值(从右到左)将其减少为单个值.
// Underscore/Lodash
var array = [0, 1, 2, 3, 4]
var result = _.reduceRight(array, function (previousValue, currentValue, currentIndex, array) {
return previousValue - currentValue
})
console.log(result)
// output: -2
// Native
var array = [0, 1, 2, 3, 4]
var result = array.reduceRight(function (previousValue, currentValue, currentIndex, array) {
return previousValue - currentValue
})
console.log(result)
// output: -2
✔ | 3.0 ✔ | 9 ✔ | 10.5 ✔ | 4.0 ✔ |
返回对象属性的个数.
// Underscore/Lodash
var result = _.size({one: 1, two: 2, three: 3})
console.log(result)
// output: 3
// Native
var result2 = Object.keys({one: 1, two: 2, three: 3}).length
console.log(result2)
// output: 3
5 ✔ | 4.0 ✔ | 9 ✔ | 12 ✔ | 5 ✔ |
测试数组中的元素是否通过由提供的函数实现的测试,只要有不通过的则立即返回.
// Underscore/Lodash
function isLargerThanTen (element, index, array) {
return element >= 10
}
var array = [10, 9, 8]
var result = _.some(array, isLargerThanTen)
console.log(result)
// output: true
// Native
function isLargerThanTen (element, index, array) {
return element >= 10
}
var array = [10, 9, 8]
var result = array.some(isLargerThanTen)
console.log(result)
// output: true
✔ | 1.5 ✔ | 9 ✔ | ✔ | ✔ |
Creates a version of the function that will only be run after first being called count times. Useful for grouping asynchronous responses, where you want to be sure that all the async calls have finished, before proceeding.
“`js
var notes = [‘profile’, ‘settings’]
// Underscore/Lodash
var renderNotes = _.after(notes.length, render)
notes.forEach(function (note) {
console.log(note)
renderNotes()
})
// Native
notes.forEach(function (note, index) {
console.log(note)
if (notes.length === (index + 1)) {
render()
}
})
“`
✔ | ✔ | ✔ | ✔ | ✔ |
检测一个值是否不是一个数字.
// Underscore/Lodash
console.log(_.isNaN(NaN))
// output: true
// Native
console.log(isNaN(NaN))
// output: true
// ES6
console.log(Number.isNaN(NaN))
// output: true
isNaN
✔ | ✔ | ✔ | ✔ | ✔ |
Number.isNaN
25 ✔ | 15 ✔ | Not supported | ✔ | 9 ✔ |
将所有可枚举属性的值从一个或多个源对象复制到目标对象.
// Underscore: _.extendOwn
// Lodash
function Foo() {
this.c = 3;
}
function Bar() {
this.e = 5;
}
Foo.prototype.d = 4;
Bar.prototype.f = 6;
var result = _.assign(new Foo, new Bar);
console.log(result);
// output: { 'c': 3, 'e': 5 }
// Native
function Foo() {
this.c = 3;
}
function Bar() {
this.e = 5;
}
Foo.prototype.d = 4;
Bar.prototype.f = 6;
var result = Object.assign(new Foo, new Bar);
console.log(result);
// output: { 'c': 3, 'e': 5 }
45 ✔ | 34 ✔ | No support | 32 ✔ | 9 ✔ |
获取一个由一个给定对象的自身可枚举属性组成的数组.
// Underscore/Lodash
var result = _.keys({one: 1, two: 2, three: 3})
console.log(result)
// output: ["one", "two", "three"]
// Native
var result2 = Object.keys({one: 1, two: 2, three: 3})
console.log(result2)
// output: ["one", "two", "three"]
5 ✔ | 4.0 ✔ | 9 ✔ | 12 ✔ | 5 ✔ |
获取一个给定对象自身可枚举属性的键值对数组.
// Underscore - also called _.pairs
// Lodash - also called _.entries
var result = _.toPairs({one: 1, two: 2, three: 3})
console.log(result)
// output: [["one", 1], ["two", 2], ["three", 3]]
// Native
var result2 = Object.entries({one: 1, two: 2, three: 3})
console.log(result2)
// output: [["one", 1], ["two", 2], ["three", 3]]
38 ✔ | 28 ✔ | Not supported | 25 ✔ | 7.1 ✔ |
返回对象自身可枚举的属性值.
// Underscore/Lodash
var result = _.values({one: 1, two: 2, three: 3})
console.log(result)
// output: [1, 2, 3]
// Native
var result2 = Object.values({one: 1, two: 2, three: 3})
console.log(result2)
// output: [1, 2, 3]
54 ✔ | 47 ✔ | Not supported | Not supported | Not supported |
构造并返回一个新字符串,该字符串包含被连接在一起的指定数量的字符串的副本.
// Lodash
var result = _.repeat('abc', 2)
// output: 'abcabc'
// Native
var result = 'abc'.repeat(2)
console.log(result)
// output: 'abcabc'
41 ✔ | 24 ✔ | Not supported | Not supported | 9 ✔ |
创建一个模板函数.
// Lodash/Underscore
const compiled = _.template('hello <%= user %>!');
compiled({ 'user': 'fred' });
// Native
const templateLitreal = (value) => `hello ${value.user}`;
templateLitreal({ 'user': 'fred' });
41 ✔ | 34 ✔ | Not supported | 28 ✔ | 9 ✔ |
将调用该方法的字符串值转换为小写形式,并返回.
// Lodash
var result = _.toLower('FOOBAR')
console.log(result)
// output: 'foobar'
// Native
var result = 'FOOBAR'.toLowerCase()
console.log(result)
// output: 'foobar'
✔ | ✔ | ✔ | ✔ | ✔ |
将调用该方法的字符串值转换为大写形式,并返回.
// Lodash
var result = _.toUpper('foobar')
console.log(result)
// output: 'FOOBAR'
// Native
var result = 'foobar'.toUpperCase()
console.log(result)
// output: 'FOOBAR'
✔ | ✔ | ✔ | ✔ | ✔ |
移除字符数组两端空格.
// Lodash
var result = _.trim(' abc ')
console.log(result)
// output: 'abc'
// Native
var result = ' abc '.trim()
console.log(result)
// output: 'abc'
5.0 ✔ | 3.5 ✔ | 9.0 ✔ | 10.5 ✔ | 5.0 ✔ |
返回一个由替换值替换一些或所有匹配的模式后的新字符串.
// Lodash
var re = /apples/gi;
var str = 'Apples are round, and apples are juicy.';
var newstr = _.replace(str, re, 'oranges');
console.log(newstr);
// output: 'oranges are round, and oranges are juicy.'
// Native
var re = /apples/gi;
var str = 'Apples are round, and apples are juicy.';
var result = str.replace(re, 'oranges');
console.log(result);
// output: 'oranges are round, and oranges are juicy.'
✔ | ✔ | ✔ | ✔ | ✔ |
删除数组中的重复元素.
// Underscore/Lodash
var result = _.uniq([1, 2, 1, 4, 1, 3]);
console.log(result)
// output: [1, 2, 4, 3]
// Native
var result = [... new Set([1, 2, 1, 4, 1, 3])]
console.log(result)
// output: [1, 2, 4, 3]
38 ✔ | 13 ✔ | 11 ✔ | 25 ✔ | 7.1 ✔ |
Chrome | Firefox | IE | Opera | Safari |
---|---|---|---|---|
✔ | 1.5 ✔ | 9 ✔ | ✔ | ✔ |