$ npm i -g npm
$ npm i --save lodash
var obj1 = {
a: 1,
b: {
c: 2
}
};
console.log(obj1); // c = 3
var obj2 = _.clone(obj1);
console.log(obj1, obj2); // c = 3
obj2.b.c = 3
console.log(obj1, obj2); // c = 3
/**
* @description: _cloneDeep(object) 深拷贝过后的数据不会影响原来的数据
* @return {object}
*/
let ob = {
a: 1,
b: 2
}
let newOb = _.cloneDeep(ob)
newOb.a = '深拷贝'
console.log('原数据', ob) // 原数据 {a: 1, b: 2}
console.log('新数据', newOb) // 新数据 {a: '深拷贝', b: 2}
/**
* @description 防抖函数 input 事件处理
* _.debounce(func, [wait=0], [options={}])
* func (Function): 要防抖动的函数。
* [wait=0] (number): 需要延迟的毫秒数。
* [options={}] (Object): 选项对象。
* [options.leading=false] (boolean): 指定在延迟开始前调用,默认false。
* [options.maxWait] (number): 设置 func 允许被延迟的最大值。
* [options.trailing=true] (boolean): 指定在延迟
*/
// input 事件进行防抖处理 当用户连续的在输入框里面连续输入的时候会重新执行函数,当用户不输入了就隔一秒执行。(用户连续触发,什么时候不连续触发了,才会执行该函数)
input.oninput = _.debounce(function fn() {
console.log('防抖')
}, 1000, {
leading: false,
trailing: true
})
// lodash 默认leading为false、trailing为true,那么最终的效果是在点击后等待1秒才会打印debounce,即延迟之前不执行函数,而是在延迟之后执行 注意 如果反过来就是 先去执行一次函数 没有防抖的效果了
/**
* @description 节流函数 按钮连续点击处理 当连续触点击,发事件只在规定的事件里执行一次(一秒内不管你点了多少次直执行一次)
* _.throttle(func, [wait=0], [options={}])
* func (Function): 要节流的函数。
* [wait=0] (number): 需要节流的毫秒数。
* [options={}] (Object): 选项对象。
* [options.leading=true] (boolean): 指定调用在节流开始前,默认true。
* [options.trailing=true] (boolean): 指定调用在节流结束后,默认true。
*/
button.onclick = _.throttle(function () {
console.log('节流')
}, 1000, { leading: false, trailing: true })
// lodash默认 trailing为 true trailing false 在一秒之内上来就执行一次
// trailing为 false trailing true 在一秒之内最后就执行一次
// vue 写法
// methods: {
// throttledMethod: _.throttle(() => {
// console.log('I get fired every two seconds!')
// }, 2000)
// }
/**
* @description: zip() 把各数组中索引值相同的数据放到一起,组成新数组
*/
console.log(_.zip(['小明', '小红', '小刚'], ['男', '女', '男'], [12, 13, 14]));
//[["小明", "男", 12],["小红", "女", 13],["小刚", "男", 14]]
/**
* @description: zipObject() 与上面方法一样,区别是它输出的是对象
*/
console.log(_.zipObject(['小明', '小红', '小刚'], ['男', '女', '男'], [12, 13, 14]));
//{小明: "男", 小红: "女", 小刚: "男"}
/**
* @description: groupBy() 按照一定规则进行分组,key为循环次数,value为匹配到的数组
*/
console.log(_.groupBy(['one', 'two', 'three'], 'length'));
//{3: ["one", "two"], 5: ["three"]}
/**
* @description: orderBy() 排序 这个封装好的可以根据对象属性名进行排序,既能升序又能降序
*/
var users = [
{ 'user': 'fred', 'age': 48 },
{ 'user': 'barney', 'age': 34 },
{ 'user': 'fred', 'age': 40 },
{ 'user': 'barney', 'age': 36 }
];
console.log(
_.orderBy(users, 'age', 'asc'), //以age属性的值进行升序排序
_.orderBy(users, 'user', 'desc'), //以user属性的值进行降序排序
);
/**
* @description: countBy() 按照一定规则统计数量,key循环次数,value为匹配到的数量
*/
console.log(_.countBy(['abc', 'efg', 'higklmn', 'abc']))//{abc: 2, efg: 1, higklmn: 1} // 按照重复的字符串统计
console.log(_.countBy(['abc', 'efg', 'higklmn', 'abc'], 'length')) // { 3: 3, 7: 1} 按每个字符串的length进行统计,length为3的有两个数据。length为5的有1个数据
/**
* @description: at() 根据传入的属性创建一个数组
*/
var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
console.log(_.at(object, ['a[0].b.c', 'a[1]'])); //[3, 4]
/**
* @description: defaults() 合并对象,与assign()一样,不过assign方法合并时遇到相同的属性,后面的会覆盖前面的。defaults刚好相反,前面的覆盖后面的
*/
console.log(
_.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }), //{a: 1, b: 2}
_.assign({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }), //{a: 3, b: 2}
);
/**
* @description: invert() 把对象的key与value颠倒,后面的属性会覆盖前面的属性
*/
var object = { 'a': 1, 'b': 2, 'c': 1 };
console.log(_.invert(object)); //{1: "c", 2: "b"}
/**
* @description: omit() 删除对象里的属性
*/
console.log(_.omit({ 'a': 1, 'b': '2', 'c': 3 }, ['a', 'c'])); //{b: "2"}
/**
* @description: defer() 推迟调用函数,在第二次事件循环的时候调用
*/
_.defer(function (text) {
console.log(text);
}, '第二次事件循环'); // 第二个输出
console.log('第一次事件循环'); //第一个输出
/**
* @description: once() 函数只能调用一次
*/
function fn3(){
console.log('fn3');
}
var newFn3=_.once(fn3);
newFn3();
newFn3(); // fn3
/**
* @description: castArray() 强制转为数组,其实就是在外面加一层方括号
*/
console.log(
_.castArray('a'), //["a"]
_.castArray({ a: 1, b: 2 }), //[{a: 1, b: 2}]
);
/**
* @description: camelCase() 转换字符串为驼峰格式
*/
console.log(
_.camelCase('kaivon_chen'), // kaivonChen
_.camelCase('kaivon chen'), // kaivonChen
);
/**
* @description: kebabCase() 转换字符为加-的形式
*/
console.log(_.kebabCase('k a i')); //k-a-i
/**
* @description: words() 把字符串的单词拆分成数组
*/
console.log(_.words('kaivon chen')); //["kaivon", "chen"]
/**
* @description: sample() 从数组中随机取一个数据
*/
console.log(_.sample(['a', 'b', 'c', 'd', 'e']));
// sampleSize() 获得 n 个随机数据
console.log(_.sampleSize(['a', 'b', 'c', 'd', 'e'], 3));
/**
* @description: _.flattenDeep(array) 将多维数组转为一维数组
* @return { Array }
*/
let arr = [13, [342, 432, [432, 43]]]
console.log(_.flattenDeep(arr)) // [13, 342, 432, 432, 43]
console.log(_.flatten(arr)) // [13, 342, 432, Array(2)] 只扁平一层 js 有方法 flat
/**
* @description: _.compact(array),去除假值。(将所有的空值,0,NaN过滤掉)
* @return { Array }
*/
let arr1 = ['', null, NaN, undefined, 0, false, true]
console.log(_.compact(arr1)) // true
/**
* @description: _.isNaN 用来判断是否为NaN
* @return { Boolean }
*/
console.log(_.isNaN(+'str')) // true
console.log(_.isNaN(42)) // false
/**
* @description: _isString
* @return { Boolean }
*/
console.log(_.isString('str')) // true
console.log(_.isString(42)) // false
/**
* @description 判断是否为undefined
* @returns 返回布尔值
*/
console.log(_.isUndefined(a.b)) // => true
console.log(_.isUndefined(a)) // => false
console.log(_.isUndefined(1)) // => false
/**
* @description get方法,用于解决a.b.c.d出现undefined导致代码报错不继续向下执行
* @param {Object} [object] 目标对象
* @param {String} [path] 需要取值路径
* @param {*} [defaultVal] 值不存在时候的默认值
*/
let obj = { 'a': [{ 'b': { 'c': 999 } }] };
console.log(_.get(obj, 'a[0].b.c')) // 999
console.log(obj.a[0].b.c) // 没有用_.get 999
// console.log(obj.a[0].k.c) // Uncaught TypeError: Cannot read properties of undefined (reading 'c') 无法读取报错
console.log(_.get(obj, 'a[0].k.c')) // 用了 _.get undefined
console.log(_.get(obj, 'a[0].k.c', 3422332)) // 第三个参数就是当无法读取属性就取第三个参数默认值
/**
*@description _getObjArray 返回指定对象的 key 的值的数组,支持多层属性嵌套获取,如:obj.x.y.z,快速获取数组内需要的key值数组
*@param {Array} [objects] 目标对象
*/
var objects = [
{ 'a': { 'b': { 'c': 2 } } },
{ 'a': { 'b': { 'c': 1 } } }
]
let _getObjArray = function (objects, path) {
return _.map(objects, _.property(path))
}
console.log(_getObjArray(objects, 'a.b.c')) // => [2, 1]
/**
*_uniq
* @description 数组去重(纯数组)
*/
var a = [1, 2, 1, 5, 1, 9]
console.log(_.uniq(a)) // => [1, 2, 5, 9]
/**
* @description: union() 取数组的并集(合并起来,去掉重复的)
*/
console.log(_.union([2], [1, 2])); //[2, 1]
/***
* @description _pick 创建一个从 object 中选中的 key 的对象。
* */
var object1 = { 'a': 1, 'b': '2', 'c': 3 }
console.log(_.pick(object1, ['a', 'c'])) // => { 'a': 1, 'c': 3 }
var object2 = { 'a': 1, 'b': '2', 'c': 3 }
console.log(_.pick(object2, ['b', 'c'])) // => { 'b': '2', 'c': 3 }
/***
* _omit
* @description 反向版 pick
*/
var object3 = { 'a': 1, 'b': '2', 'c': 3 }
console.log(_.omit(object3, ['a', 'c'])) // => { 'b': '2' }
/**
* @description: chunk() 把数组拆分成一个二维数组,拆分后的第1个数组的长度为第二个参数的值
*/
console.log(_.chunk(['a', 'b', 'c', 'd'], 2)); //[["a", "b"],["c", "d"]]
/**
* @description: difference() 在第一个数组中把第二个数组里的数据都排除掉
*/
console.log(_.difference([1, 3, 5, 7, 9], [3, 7])); // [1, 5, 9]
/**
* @description: drop() 切掉数组的前n(第二个参数,默认为1)位
*/
console.log(_.drop(['a', 'b', 'c', 'd', 'e'], 2)); //['c', 'd', 'e']
/**
* @description: difference() 在第一个数组中把第二个数组里的数据都排除掉
*/
//dropRight() take() 保留数组的前n(第二个参数,默认为1)位。与drop方法相反
console.log(_.take(['a', 'b', 'c', 'd', 'e'], 2));