前端自省系列😆有些是掘友的一些专栏文章的摘录,如果有不对的地方,请大家指出
判断移动设备来源
//移动设备来源判断
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执行时,遇到同步任务,放到主线程进行执行,遇到异步任务会放到异步队列,异步队列分为宏任务和微任务
- 主线程任务执行完毕,从微任务队列中获取任务,放到主线程进行执行
- 微任务队列完成后,再从宏任务获取任务,如果又遇到微任务,则放到微任务队列,当前宏任务完成后,获取队列中的微任务,所有微任务执行完成在继续获取宏任务执行.(不断循环)
宏任务
setTimeOutsetIntervalsetImmediate
微任务
- 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);