javascript高级知识

标签: Javascript 分类: Javascript 创建时间:2020-04-02 03:03:19 更新时间:2025-01-17 10:39:23

1.”a”==true 和 “a”==false 结果都是false ?

今天有同事问我:”a”==true 和 “a”==false 结果都是false ? 我也答不上来,但是 “1” == true 返回的是 true。

经过查询资料,抽象比较算法的具体过程如下:

根据图示,那就好解释了。”a” 和 true 属于不同的类型,Type(true) 为Boolean 类型,所以两者返回的结果是 x==ToNumber(y) 的结果,即 “a”== 1。继续往下走,结果符合第五条的条件,即 Type(x) 为 String 且 Type(y) 为 Number,返回比较ToNumber(x)==y的结果,即ToNumber(“a”) == 1,即 NaN == 1 ,typeof(NaN)为number,typeof(1)也为number。

两个类型相同的进行比较,符合条件1,又因为x为NaN,所以符合条件c的第一条,返回false,整个比较过程结束。同理 “a” == false 最后也会转换为NaN和1的比较,也符合 1.c.i 条,结果为false。这样也可以解释为什么”1” == true 返回的是true了。
因为 “1” == true,符合第八条,返回比较 x== ToNumber(y) 的结果,即返回 “1” == 1 的结果。又因为 “1” == 1的比较符合第五条,则返回 ToNumber(x) == y的结果,即返回 1 == 1 的结果,继续比较,则符合 1.c.iii 条,所以结果为true。

不知道是否对,应该是这么分析的吧。

2.pako压缩

需求是这样的,后端传回来了很多的数据,为了减少网络请求,老板要求,把数据存储到本地中,但是使用localStroage存储的话会有配额限制,于是老板就想了一个好招,先用js进行压缩,然后在进行存储啊。于是,就开启了我的gzip压缩之路,首先找到的就是pako这个js代码库。

需要说明的是:1.服务器开启了Gzip压缩,数据传到前台之后,前台是自动解压缩的,不需要前端程序员干扰。2.pako并不是万能的压缩工具,它对于某些特定文件(图片,视频,pdf等)均没有很好的压缩效。

这个库用起来也非常的简单,引入压缩库,然后执行压缩和解压缩

1
2
3
4
5
6
7
8
9
10
11
12
<script src="./static/lib/pako.min.js"></script>

<script>
// 压缩数据
var gzipdata=pako.deflate(JSON.stringify(data), { to: 'string' })
// 保存数据
sessionStorage.setItem(sectionId+"_"+start_time+"_"+end_time,gzipdata);

// 解压缩数据
var restored = JSON.parse(pako.inflate(gzipdata, { to: 'string' }));

</script>

3.localStorage 存满了怎么办?

各主流浏览器(包含PC、移动端)都是 5M 的数量级。 值得说明的是,安卓上手 Q 、手机QQ浏览器、微信中则是 2.5M 的数量级,因此在移动端,本地存储的 SIZE 更加珍贵。 综上,SIZE 在 2 - 5M 的区间。Cookie是4096字节,也就是4k的大小。

localStorage存不下了怎么办?那就清空全部的缓存,然后重写存储啊。

1
2
3
4
5
6
7
8
9
10
11
const QUOTA_EXCEEDED_ERR_CODE = 22
function write (key, data) {
try {
localStorage.setItem(key, data);
} catch (e) {
if (e.code === QUOTA_EXCEEDED_ERR_CODE) {
localStorage.clear();
localStorage.setItem(key, data);
}
}
}
参考文章:
1.localStorage 存满了怎么办? (localStorage存满了,就会报错)
2.使用localStorage必须了解的点
3.避免localStorage被更改 让localStorage禁止修改值 (还可以监听windows的storage事件,禁止修改localStorage的值)

4.原生实现的效果

(1) tab页

参考文章:
1.JS 自定义属性实现Tab切换 (这篇文章非常有用)
2.原生JS实现TAB栏切换

5.SameValueZero比较算法

最近使用array.indexOf(),查询数组中是否有某个值。

5.webp图片格式

这种格式是什么,有什么有点,我就不说了,就是摘抄下,优雅降级的方法,参考文章2中的内容。
(1) 使用picture标签

(2) 使用js检测是否支持

(3) 后端处理

参考文章:
1.使用webp图片提升前端性能 (这篇文章不仅讲了如何使用webp格式的图片,还讲了如何进行优雅的降级)
2.webp图片降级方案有哪些 (这个github问答中,讲了三种优雅降级的方法)
3,Vuejs webp图片支持,插件开发过程~ (这是一个插件开发者的开发历程)
4.vue项目下一些浏览器不支持图片的.webp格式的处理 (也是js方法检测时候支持webp,只不过用了vue语法写了一下。)

6.利用js代码阻止用户打开控制台

今天打开一个网站 (可能作者也不想让我们看到他的代码),发现了一个奇怪的现象,就是每当我想要打开控制台,查看页面的js代码的时候,页面就跳转到了一个自定义的网站,刚开始我还以为是我操作错误,反复操作之后,还真是出现了这个现象,于是我上网谷歌了一下。

1
2
3
4
//debug调试时跳转页面
var element = new Image();
Object.defineProperty(element,'id',{get:function(){window.location.href="http://www.baidu.com"}});
console.log(element);

解决方法就是使用书签管理器监听beforeunload事件,点击【右上角一排竖点】->【书签】->【书签管理器】->【右上角一排竖点】->【添加新书签】

将打开下面这个书签管理窗口,然后名称随便写,网站输入下面的内容,保存。

1
javascript:window.addEventListener('beforeunload', function (e) { e.preventDefault();e.returnValue = '' });

在阻止跳转的网页上,先点击这个阻止跳转的书签,然后就可以打开控制台了。在弹出的提示框中选择取消,就可以留在这个页面了。

参考文章:
1.阻止某些网站中,debug调试跳转页面的方法 (这里是讲的如何破解这种利用js阻止用户打开控制台的方法)
2.页面前端一打开控制台就会跳转到一个提示页面怎么解决
3.利用书签执行js脚本 (这篇文章使用书签来执行代码,还真是不错,连下载百度文库貌似都能做到,不过没有实验)

7.padding无法触发点击事件

今天遇到一个怪事,就是一个元素设置了padding之后,点击padding部分,元素的点击事件不响应。

参考文章:
1.margin和padding的坑

8.事件代理

使用事件代理,可以很好的解决元素绑定事件带来的内存消耗问题。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
function eventDelegate (parentSelector, targetSelector, events, foo) {
// 触发执行的函数
function triFunction (e) {
// 兼容性处理
var event = e || window.event;

// 获取到目标阶段指向的元素
var target = event.target || event.srcElement;

// 获取到代理事件的函数
var currentTarget = event.currentTarget;

// 遍历外层并且匹配
while (target !== currentTarget) {
// 判断是否匹配到我们所需要的元素上
if (target.matches(targetSelector)) {
var sTarget = target;
// 执行绑定的函数,注意 this
foo.call(sTarget, Array.prototype.slice.call(arguments))
}

target = target.parentNode;
}
}

// 如果有多个事件的话需要全部一一绑定事件
events.split('.').forEach(function (evt) {
// 多个父层元素的话也需要一一绑定
Array.prototype.slice.call(document.querySelectorAll(parentSelector)).forEach(function ($p) {
$p.addEventListener(evt, triFunction);

// 保存事件处理,可以移除
$p[evt]=triFunction;
});
});
}


/// 使用
function click() { console.log(this);
eventDelegate('#list', 'li', 'click', click});

// 移除
let mapDom=document.querySelector("#list");
mapDom.removeEventListener("click",mapDom.mousedown);
参考文章:
1.JavaScript 事件委托详解 (借助于这篇文章,我实现了事件代理,但是有一个缺点,就是无法移除事件代理,经过修改,解决了事件移除的问题)
2.js中的事件代理(event delegation) (这篇还没看)

9.视频截图

我使用了 video 进行了屏幕截图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/**
* 视频截图
*/
function screenShot() {
var video = videoRef.value; // 找到需要截图的video标签
var canvas = document.createElement('canvas');
if (video && canvas) {
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height); // 图片大小和视频分辨率一致
var strDataURL = canvas.toDataURL('image/png'); // canvas中video中取一帧图片并转成dataURL
var arr = strDataURL.split(','),
mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]),
n = bstr.length,
u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
var blob = new Blob([u8arr], {
type: mime,
});
var url = window.URL.createObjectURL(blob);
var a = document.createElement('a');
a.style.display = 'none';
a.href = url;
a.download = '截图.png';
document.body.appendChild(a);
a.click();
setTimeout(function () {
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
}, 1000);
}
}
参考文章:
【1】.JS 截取视频某一帧图片 实现视频截图 1.创建video用于存放需要截取的视频文件。2.创建canvas画布,用于绘制截取到的图片。
【2】.使用getDisplayMedia在元素下面的所有DIVs的Chrome中执行屏幕截图
【3】.js从video中截图并下载 这里提供了大部分的代码,我只是做了一个修改
【4】.webrtc入门:2.使用getDisplayMedia获取屏幕桌面流 在会议系统中,我们有时不仅仅需要摄像头的数据,在一些场景下,需要演示桌面上的程序,同样的webrtc也提供了这个功能,而且都可以从浏览器上直接获取。
【5】.js 浏览器截屏的两种方式,html2canvas和MediaDevices.getDisplayMedia() MediaDevices.getUserMedia() 这个方法是浏览器自带的Web Api,可以在用户授权后共享整个屏幕、应用窗口、标签页,可在第一段的链接查看浏览器的支持情况。
【6】.[译]在浏览器中如何使用JavaScript截图 1.使用canvas的优点:快、良好的浏览器兼容性;缺点:不支持Shadow DOM(或Web Component、跨域限制、并不是所有的CSS属性都能支持。2.getDisplayMedia API的优点:良好的现代浏览器支持,可扩展性、桌面 || 标签页 ;缺点:权限 、慢。3.截图服务优点:后处理、健壮性;缺点:无状态、成本和时间

10.屏幕截图

上面的代码实现了视频截图,还有就是整个屏幕的截图。

参考文章:
【1】.利用canvas实现视频截图 canvas实现截图方法实现的原理就是使用的canvas的drawImage方法实现,这个方法能传入的语法格式有三种。
【2】.vue3中,使用html2canvas截图包含视频、图片、文字的区域 通过配置跨域设置,进行了视频的截图,crossorigin=”anonymous” 这里我暂时没有尝试过。
【3】.html2canvas怎么从视频上截图,我整出来居然是一张空白图片 这里问题差不多,但是没有最终的答案。
小额赞助
本人提供免费与付费咨询服务,感谢您的支持!赞助请发邮件通知,方便公布您的善意!
**光 3.01 元
Sun 3.00 元
bibichuan 3.00 元
微信公众号
广告位
诚心邀请广大金主爸爸洽谈合作
每日一省
isNaN 和 Number.isNaN 函数的区别?

1.函数 isNaN 接收参数后,会尝试将这个参数转换为数值,任何不能被转换为数值的的值都会返回 true,因此非数字值传入也会返回 true ,会影响 NaN 的判断。

2.函数 Number.isNaN 会首先判断传入参数是否为数字,如果是数字再继续判断是否为 NaN ,不会进行数据类型的转换,这种方法对于 NaN 的判断更为准确。

每日二省
为什么0.1+0.2 ! == 0.3,如何让其相等?

一个直接的解决方法就是设置一个误差范围,通常称为“机器精度”。对JavaScript来说,这个值通常为2-52,在ES6中,提供了Number.EPSILON属性,而它的值就是2-52,只要判断0.1+0.2-0.3是否小于Number.EPSILON,如果小于,就可以判断为0.1+0.2 ===0.3。

每日三省
== 操作符的强制类型转换规则?

1.首先会判断两者类型是否**相同,**相同的话就比较两者的大小。

2.类型不相同的话,就会进行类型转换。

3.会先判断是否在对比 null 和 undefined,是的话就会返回 true。

4.判断两者类型是否为 string 和 number,是的话就会将字符串转换为 number。

5.判断其中一方是否为 boolean,是的话就会把 boolean 转为 number 再进行判断。

6.判断其中一方是否为 object 且另一方为 string、number 或者 symbol,是的话就会把 object 转为原始类型再进行判断。

每日英语
Happiness is time precipitation, smile is the lonely sad.
幸福是年华的沉淀,微笑是寂寞的悲伤。