让前端飞Web前端之路

js中常用的函数

2020-03-08  本文已影响0人  子皙丶

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);
// 二者互不影响
上一篇 下一篇

猜你喜欢

热点阅读