js中常用的函数
1. js中类型判断
let isType = (type , obj)=> {
return Object.prototype.toString.call(obj) === `[object ${type}]`
}
isType('Number', 1) //true
isType('String', '123') // true
isType('Boolean' , true) //true
isType('Array', [1,2,3]) //true
isType('Object' , {a:1}) //true
isType('Function' , function a(){}) //true
2. for in 和 Object.keys的区别
for in 会遍历对象本身属性以及自定义的属性和原型链上自定义的属性
var obj = {name : 'ding'}
Object.defineProperty(obj, 'age', {
enumerable : true,
value : true
})
Object.prototype.like = 'eat'
for (let k in obj){
console.log(k) // name age like
}
Object.keys 只会遍历本身属性和自定义的属性,不会遍历原型链上自定义的属性
var obj = {name : 'ding'}
Object.defineProperty(obj, 'age', {
enumerable : true,
value : true
})
Object.prototype.like = 'eat'
console.log(Object.keys(obj)) // name age
3. 缓存函数
缓存函数一般多应用于,需要大量重复的调用函数时,并且可能多次是参数一样的重复调用
hasher可有可无,哈希的目的也是记录参数的唯一性
let memoize = function (func, hasher){
var memoize = function(){
var cache = memoize.cache
var address = '' + (hasher ? hasher.apply(this, arguments) : arguments)
if(!cache[address]){
cache[address] = func.apply(this, arguments)
}
return cache[address]
}
memoize.cache = {}
return memoize
}
使用例子
var add = function(a , b){
console.log('add')
return a+b
}
var calculate = memoize(add)
var one = calculate(2,3)
var two = calculate(2,3)
var three = calculate(2,3)
// 只打印一个 add
//这里调用了三次,但是add函数只调用了一次,大大的节省了时间和性能
4. reduce函数
参考文档
arr.reduce(callback(prev, cur, index, array) , initialValue)
第一个参数是callback函数,第二个参数是初始值
callback中第一个参数是累计值,也就是上一次执行完后返回的结果,第二个参数是当前值,第三个是当前值的索引,第四个参数是源数组
// 求和
var arr = [1,2,3]
var sum = arr.reduce(function(prev, cur){
return prev + cur
},0)
console.log(sum) // 6
// 数组去重
var arr2 = [1,2,3,4,5,6,6,3,4]
var newArr = arr2.reduce((prev, cur) => {
prev.indexOf(cur) === -1 && prev.push(cur)
return prev
},[])
console.log(newArr) // [1,2,3,4,5,6]
5. 复合函数compose
目的:将多个纯函数组合到一起
let compose = function () {
let args = [].slice.call(arguments)
return function(x){
return args.reduceRight((res, fn)=>{
return fn(res)
},x)
}
}
let pipe = function () {
let args = [].slice.call(arguments)
return function(x){
return args.reduce((res, fn)=>{
return fn(res)
},x)
}
}
上面两个函数一样,只不过参数的执行顺序不同,一个是从右往左,一个从左往右执行。
举个例子,对一个数字 先加10 再乘10
let add = x => x+10
let multiply = x => x*10
let fn1 = compose(multiply, add) // 执行顺序是从右往左执行
let res1 = fn1(10) // 200
let fn2 = pipe(add, multiply) //执行顺序是从左往右执行
let res2 = fn2(10) // 200
6. 过滤函数filter
// filter
let persons = [
{ 'name': 'Peter', age: 21 },
{ 'name': 'Mark', age: 28 },
{ 'name': 'Josn', age: 19 },
{ 'name': 'Jane', age: 31 },
{ 'name': 'Tony', age: 35 }
]
let newAge = persons.filter(item => item.age > 21);
console.log(newAge);
7. 防抖与节流
参考这里
8. 浅拷贝和深拷贝
let deepClone = obj => {
let newObject = Array.isArray(obj) ? [] : {}
if(obj && typeof obj === 'object'){
for(let key in obj){
// 使用hasOwnProperty的目的是确保不去遍历原型链上的属性
if(obj.hasOwnProperty(key)){
// 如果属性值仍是对象,则递归调用
if(obj[key] && typeof obj[key] === 'object'){
newObject[key] = deepClone(newObject[key])
}else{
// 如果不是,则直接赋值
newObject[key] = obj[key]
}
}
}
}
return newObject
}
举个例子:
let richGirl = {
name: '开心',
car: ['宝马', '奔驰', '保时捷'],
deive: function () { },
age: undefined
}
let richBoy = deepClone(richGirl);
richBoy.deive = '渣男开大G';
richBoy.name = '小明';
richBoy.car = ['哈罗单车', '膜拜'];
richBoy.age = 20;
console.log(richGirl);
console.log(richBoy);
// 二者互不影响
发表评论 (审核通过后显示评论):