关于JS的一些方法

133 阅读4分钟

这篇文章是笔者负责前端开发总结的一些经验,沉淀下来的开发经验,大家各取所需,不喜勿喷~当然啦,有自己的见解、更好的建议的大牛朋友们,我们评论区见~hhh,大🔥多提点高见,让笔者继续学习继续进步!

一、遍历Object

Object.entries(obj).forEach(([key, value]) => { 
    console.log(`${key} is ${value}`) 
}) 
Object.keys({ a:1, b: 2 }) // 遍历Key ["a", "b"]

for(const key in { a:1, b: 2 }){
    console.log(key) // a b
}

二、 找数组最相近的值

var addSp = 0; 
var speedLen = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18]; 
function near(a,b){ 
    var c, d, e; 
    for(var i = 0;i < a.length; i++ ){ 
        i == 0 && (c = a[i], e = Math.abs(b - a[i] )); 
        a[i] > b && (d = d ? (a[i] < d ? a[i] : d) : a[i]); 
        i > 0 && (Math.abs(b - a[i]) < e && (c = a[i], e = Math.abs(b -a[i])));
    } 
    // a 最接近值,b 大于本数的最小值 
    return { a : c, b : d } 
} 
console.log('最接近的值', near(speedLen,addSp)['a']) 
console.log('大于本数的最小值', near(speedLen,addSp)['b'])

// 最相近的对象值 
var addSp = 200; 
var speedLen = [{ a: 100 }, { a: 50 }, { a: 10 }]; 
function near(a,b,property){ 
    var c, d, e; 
    for(var i = 0;i < a.length; i++ ){ 
        i === 0 && (c = a[i], e = Math.abs(b - a[i][property] )); 
        a[i][property] > b && (d = d ? (a[i][property] < d[property] ? a[i] : d) : a[i]); 
        i > 0 && (Math.abs(b - a[i][property]) < e && (c = a[i], e = Math.abs(b - a[i][property]))); 
    } 
    // a 最接近值,b 大于本数的最小值 
    return { a : c || d, b : d || c } 
} 
console.log('最接近的值', near(speedLen,addSp,'a')['a']) 
console.log('大于本数的最小值', near(speedLen,addSp,'a')['b'])

三、List去重

const arr1 = [ 
    {id: 1, sku: 101, name: 'sku103'}, 
    {id: 2, sku: 102, name: 'sku102'}, 
    {id: 3, sku: 103, name: 'sku103'}, 
] 
function deduplication(arry, prop){ 
    const hash = {}; 
    const arr = arry.reduce(function(resultArray, item) { 
        hash[item[prop]] ? '' : hash[item[prop]] = true && resultArray.push(item); 
        return resultArray 
    }, []) 
    return arr 
} 
deduplication(arr1, 'name') // 去重后的数组

四、判断是不是伪数组

export const isFakeArray = (o) => { 
    return !!(o && // o非null undefined 
    typeof o === 'object' && // o是对象 
    isFinite(o.length) && // o.length是有限数值 
    o.length > 0 && // o.length为非负数 
    o.length === Math.floor(o.length) && // o.length是整数 
    o.length < 4294967296) 
}

五、indexOf在对象中的用法

var arr =[ {name:'zhangsan'}, {name:'lisi'}, {name:'wangwu'} ]; 
var json2 = arr[0]; 
var json3 = {name:'zhangsan'}; 
console.log('json2',arr.indexOf(json2)); // 存在
console.log('json3',arr.indexOf(json3)); //不存在

六、判断类型

typeof [] // object 
Object.prototype.toString.call([]) // [object Array] 

typeof {} // object 
Object.prototype.toString.call({}) // [object Object]

typeof function(){} // function
Object.prototype.toString.call(function(){}) // [object Function]

typeof new RegExp() // object 
Object.prototype.toString.call(new RegExp()) // [object RegExp] 

typeof new Date() // object 
Object.prototype.toString.call(new Date()) // [object Date] 

typeof null // object 
Object.prototype.toString.call(null) // [object Null] 

typeof 1// object 
Object.prototype.toString.call(1) // [object Number] 

typeof false // boolean 
Object.prototype.toString.call(false) // [object Boolean]

八、查找对象里面最大值和最小值

Math.min.apply(Math, array.map(o => o.x))
Math.max.apply(Math, array.map(o => o.x))

九、防抖函数

/** 
  * @param {Function} func 
  * @param {number} wait 
  * @param {boolean} immediate 
  * @return {*} 
  */ 
  export function debounce(func, wait, immediate) { 
      let timeout, args, context, timestamp, result
      
      const later = function() { 
          // 据上一次触发时间间隔 
          const last = +new Date() - timestamp 
          // 上次被包装函数被调用时间间隔last 小于设定时间间隔 wait 
          if (last < wait && last > 0) { 
              timeout = setTimeout(later, wait - last) 
          } else { 
              timeout = null // 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用 
              if (!immediate) { 
                  result = func.apply(context, args) 
                  if (!timeout) context = args = null 
              } 
           } 
      } 
      
      return function(...args) { 
          context = this timestamp = +new Date() 
          const callNow = immediate && !timeout 
          // 如果延时不存在,重新设定延时 
          if (!timeout) timeout = setTimeout(later, wait) 
          if (callNow) { 
              result = func.apply(context, args) context = args = null 
          } 
          
          return result 
      } 
} 
// 使用方法 
mounted() { 
    this.$nextTick(() => { 
        window.addEventListener('resize', this.debounceResize = debounce(() => { console.log(1) }), false) 
        this.$once('hook:beforeDestroy', () => window.removeEventListener('resize', this.debounceResize, false)) 
    }) 
} 

// 使用方法(第一次不会执行,第二次调用this.throttleBasicData()实现效果) 
mounted() { 
    this.throttleBasicData = debounce(()=>{ console.log(55) }})) // 注册throttleBasicData方法在实例上 
}

十、js数组中随机选取一个数值!!

var arr = ["太阳光大","成功是优点的发挥","不要小看自己""口说好话","手心向下是助人" ]; 
alert(arr[Math.floor((Math.random()*arr.length))]);

十一、事件

// 监听当前窗口是否处于后台状态 
document.addEventListener("visibilitychange"e => { 
    console.log(4444) 
});

十二、判断数组中是否有该值

[1, 3, 'echo'].includes('echo'); //true

十三、判断对象里面是否有该属性

Reflect.has({x: 0}, 'x'); // true

十四、数组求和

const sumBy = (arr, fn) => 
    arr
    .map(typeof fn === 'function' ? fn : val => val[fn])
    .reduce((acc, val) => acc + val, 0); 
     
    sumBy([{ n: 4 }, { n: 2 }, { n: 8 }, { n: 6 }], x => x.n); // 20 
    sumBy([{ n: 4 }, { n: 2 }, { n: 8 }, { n: 6 }], 'n'); // 20

十五、[].slice.call解释

[].slice.call(arguments, 1) 
其含义相当于 arguments.slice(1),就是取出所有参数,并从下标为1开始,截取所有。

十六、videos标签的一些方法

mounted() { 
    this.$nextTick(() => { 
        const videoRef = this.$refs.videoRef 
        videoRef.addEventListener('loadedmetadata', () => { // 加载数据 
            console.log(videoRef.duration) // 视频总长度
        }) 
        videoRef.addEventListener('play', () => {
            console.log('开始播放') 
        }) 
        videoRef.addEventListener('playing', () => { 
            console.log('播放中') 
        }) 
        videoRef.addEventListener('waiting', () => {
            console.log('加载中') 
        }) 
    }) 
},

十七、判断数组中是否有重复值

    let arr = [1,2,3] 
    new Set(arr).size !== arr.length

十八、伪数组转数组

    [].slice.call(arguments)

十九、深拷贝

// 定义一个深拷贝函数 接收目标target参数 
function deepClone(target) { 
    // 定义一个变量 
    let result; // 如果当前需要深拷贝的是一个对象的话 
    if (typeof target === 'object') { // 如果是一个数组的话 
        if (Array.isArray(target)) { 
            result = []; // 将result赋值为一个数组,并且执行遍历 
            for (let i in target) { // 递归克隆数组中的每一项 
                result.push(deepClone(target[i])) 
            } 
         // 判断如果当前的值是null的话;直接赋值为null 
         } else if(target===null) { 
             result = null; 
             // 判断如果当前的值是一个RegExp对象的话,直接赋值 
         } else if(target.constructor===RegExp){ 
             result = target; 
         } else { 
             // 否则是普通对象,直接for in循环,递归赋值对象的所有值 
             result = {}; 
             for (let i in target) { 
                 result[i] = deepClone(target[i]); 
             } 
         } 
     // 如果不是对象的话,就是基本数据类型,那么直接赋值 
     } else { 
        result = target; 
     } 
     // 返回最终结果 
     return result; 
     }
     

二十、bind、apply、call的用法

var person = { 
    firstName: '八', 
    lastName: '神', 
    fullName: function() { 
        console.log(this) 
        return this.firstName + " " + this.lastName; 
    } 
}
var person1 = { firstName:"Bill", lastName: "Gates" }
var x = person.fullName.apply(person1); // 里面的this指向person1 
var x = person.fullName.apply(null); // 里面的this指向windows 
var x = person.fullName(); // 里面的this指向person 

call 、bind 、 apply 这三个函数的第一个参数都是 this 的指向对象,第二个参数差别就来了 call 的参数是直接放进去的,第二第三第 n 个参数全都用逗号分隔,直接放到后面 obj.myFun.call(db,'成都', ... ,'string' )。 
apply 的所有参数都必须放在一个数组里面传进去 obj.myFun.apply(db,['成都', ..., 'string' ])。 
bind 除了返回是函数以外,它的参数和call一样。