自省系列JS-2

158 阅读4分钟

前端自省系列😆有些是掘友的一些专栏文章的摘录,如果有不对的地方,请大家指出

判断移动设备来源

//移动设备来源判断
function deviceType() {
    //获取userAgent,判断Agent中是否包含设备特殊字符
    const ua = navigator.userAgent;
    const agent = ["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"];
    //判断ua中是否包含标识符
    return agent.filter(item => ua.indexOf(item) > -1);
}

//是否为微信判断
function isWx() {
    const ua = navigator.userAgent;
    //根据关键字 MicroMessenger 来判断是否是微信内置的浏览器
    return ua.mathch(/MicroMessenger/i) === "micromessenger" ? true : false;
}

获取数组最大,最小值

function maxAndMinOfArr(arr) {
    //apply->null 代表的是全局对象
    //apply 第二个参数是以数组形式传递
    //只考虑了一维数组,如果多维可降维或扁平化处理
    const max = Math.max.apply(null,arr);
    const min = Math.min,apply(null,arr);
}

this简易理解

谁调用我,我就指向谁

  • 代表执行环境上下文
  • 全局环境在浏览器中是windows
  • 函数中的this指向调用者
  • 构造函数指的是以此构造函数实例化后的对象
  • bind,call,apply可以更改this的指向

返回已空格分隔的单词中,最长的单词

function maxLengthOfWorld(str) {
    //转化为数组处理
    str.split(" ").reduce((pre,cur) => {
        return pre.length > cur.length ? pre : cur;
    })
}

eval

  • 不安全的
  • 将传入的字符串当做 JavaScript 代码进行执行
  • 性能低,因为只有在执行eval时,才会调用JS解释器进行编译,无法经过编译器的优化
  • eval作用域混乱

跨域

  • 什么时候触发跨域

    不同源的时候会触发.浏览器同源策略指的是协议相同,host相同,端口相同

  • 为什么浏览器禁止跨域

    CSRF攻击:跨站请求伪造,攻击者盗用了你的身份,以你的名义发送恶意请求 比如: 当你登录A网站,本地生成cookie,此时你又去访问B网站,B网站获取了A的cookie请求A网站.此时就等于你的账号相关权限B同样可以拥有访问

  • 跨域解决方案

    • JSONP: 通过script可以跨域的原理,请求接口,执行服务端的回调函数.但是只能是GET请求
    • iframe
    • form
    • CORS: 跨域资源共享,需要后端配合
    • nginx代理

IIFE的理解

  • 立即执行函数,函数创建后立即执行
  • 独立作用于,变量私有化,无法直接访问到,避免变量冲突
  • 避免全局作用域的污染

创建对象的方式

  • 字面量 {}
  • 构造函数创建: new Object()
  • Object.create(null): 此时不继承Object的原型

事件冒泡

  • 事件执行顺序,捕获阶段->目标阶段->冒泡阶段.
  • 冒泡是指从事件源开始,一直向上传递,一直到document,如果父级也存在同样类型的事件时,也会被触发
  • 可以通过event.stopPropagation阻止冒泡

EventLoop

执行顺序

  • JS引擎有多个线程,但是同一时间只执行一个任务,其他任务会放到队列中.
  • JS执行时,遇到同步任务,放到主线程进行执行,遇到异步任务会放到异步队列,异步队列分为宏任务和微任务
  • 主线程任务执行完毕,从微任务队列中获取任务,放到主线程进行执行
  • 微任务队列完成后,再从宏任务获取任务,如果又遇到微任务,则放到微任务队列,当前宏任务完成后,获取队列中的微任务,所有微任务执行完成在继续获取宏任务执行.(不断循环)

宏任务

  • setTimeOut
  • setInterval
  • setImmediate

微任务

  • Promise

获取两个时间差

/**
 * 获取两个时间差
 * @param {Date} endAt 
 * @param {Date} startTime 
 */
function diffDateTime(endAt, startTime = new Date()) {
  const endTime = new Date(endAt);
  //计算两个时间相差毫秒
  const dateDiff = endTime.getTime() - startTime.getTime();
  //天数
  const dayDiff = Math.floor(dateDiff / (24 * 60 * 60 * 1000));

  //小时 取模获取计算天数后剩余小时数的毫秒
  const hourMs = dateDiff % (24 * 60 * 60 * 1000);
  const hours = Math.floor(hourMs / (60 * 60 * 1000));

  //分钟 取模获取经计算小时剩余分钟数的毫秒
  const minutesMs = hourMs % (60 * 60 * 1000);
  const minutes = Math.floor(minutesMs / (60 * 1000));

  //秒 取模获取计算分钟后剩余秒的毫秒
  const secondMs = minutesMs % (60 * 1000);
  const seconds = Math.floor(secondMs / 1000);

  return dayDiff + "天" + hours + "小时" + minutes + "分" + seconds + "秒";
}

console.log(diffDateTime("2020-05-16 18:05:00")); //0天0小时24分44秒

求N的阶乘

const factorial = (num) => num === 1 ? num : num * factorial(num - 1);