void
void其实是javascript中的一个函数,接受一个参数,返回值永远是undefined void expression
1 | void 0 |
Element.scrollIntoViewIfNeeded
Element.scrollIntoViewIfNeeded()方法用来将不在浏览器窗口的可见区域内的元素滚动到浏览器窗口的可见区域。 如果该元素已经在浏览器窗口的可见区域内,则不会发生滚动。
1
2
3element.scrollIntoView(); // 等同于element.scrollIntoViewIfNeeded(true)
element.scrollIntoViewIfNeeded(true);
element.scrollIntoViewIfNeeded(false);
- 当元素已经在可视区域时,调用 Element.scrollIntoView(),无论设置什么参数,均发生滚动。
- 当元素已经在可视区域时,调用 Element.scrollIntoViewIfNeeded(),无论设置什么参数,均不发生滚动。
JS取整数部分
1 | ~~2.5 // 2 按位取反 -2^31~2^31-1 -2147483648~2147483647 |
与Math.floor()的对比
区别 | Math.floor | ~~ |
---|---|---|
NaN | NaN | 0 |
+0 | +0 | 0 |
-0 | -0 | 0 |
+Infinity | +Infinity | 0 |
-Infinity | -Infinity | 0 |
1.2 | 1.2 | 1.2 |
-1.2 | -1 | -1 |
1 | 1. 位运算:~ 的结果是 int32 的有符号整数,所以肯定不可能是 NaN 和无穷 x|0 x^0 x<<0 x>>0 |
在没有指定基数,或者基数为 0 的情况下,JavaScript 作如下处理: 如果字符串 string 以”0x”或者”0X”开头, 则基数是16 (16进制). 如果字符串 string 以”0”开头, 基数是8(八进制)或者10(十进制),那么具体是哪个 基数由实现环境决- 定。ECMAScript 5 规定使用10,但是并不是所有的浏览器都遵循这个 规定。因此,永远都要明确给出radix参数的值。 如果字符串 string 以其它任何值开头,则基数是10 (十进制)。
1 | parseInt(0.0000000003) // 3 |
- parseFloat(string)
它的规则与parseInt基本相同,但也有点区别:字符串中第一个小数点符号是有效的,另外parseFloat会忽略所有前导0,如果字符串包含一个可解析为整数的数,则返回整数值而不是浮点数值。
1
2
3
4
5parseInt("0xA") // 10
parseFloat("0xA") // 0
parseInt(".1") // NaN
parseFloat(".1") // 0.1
js取小数部分
1 | function fract(num) { |
JS浮点数运算(原因浮点数无法用二进制准确表示)
1 | 0.1+0.2 // 0.30000000000000004 |
Object.toString()
1 | var a = {name:'cosyer'} |
全等判断
javascript 中 +0 完全等于 -0,那么怎么分区两者呢?
1 | 1/0 === 1/-0 // false |
区分NaN
1 | NaN !== NaN // true |
判断NaN
1 | Number.isNaN(); // true 与isNaN全局函数相比,不存在类型转换更加严格 |
isFinite
判定一个数字是否是有限数字(如果参数是 NaN,正无穷大或者负无穷大,会返回false,其他返回 true)
1
2
3
4
5
6isFinite(Infinity); // false
isFinite(NaN); // false
isFinite(-Infinity); // false
isFinite(0); // true
isFinite(2e64); // true, 在更强壮的Number.isFinite(null)中将会得到false
isFinite("0"); // true, 在更强壮的Number.isFinite('0')中将会得到false
try-catch跳出forEach循环
forEach遍历不能保证遍历的顺序,以及不能break;一般for循环的性能是forEach的20倍
1 | try { |
fetch模拟post进行api测试
1 | fetch(apiUrl, { |
实现var a = add(2)(3)(4) 函数柯里化
js中console.log一个对象时,会对这个对象进行toString()操作,还有些情况会对对象进行valueOf()操作 vauleOf优先于toString()被调用
1 | function add(num){ |
阶乘
1 | function factorial(num){ |
arguments.callee的替换方案
1 | function show(n) { |
Date相关
Date构造函数
1 | 4种表示时间戳的方式 |
当前时间
1 | let d = new Date() |
Date计时
以博客存活时间为例
1 | var time = new Date(); |
Date原型扩展方法
1 | Date.prototype.format = function (format) { |
页面加载时间
1 | window.onload = function () { |
onload和onready的区别:
- 执行时间
window.onload必须等到页面内包括图片的所有元素加载完毕后才能执行。
$(document).ready()是DOM结构绘制完毕后就执行,不必等到加载完毕。
- 编写个数不同
window.onload不能同时编写多个,如果有多个window.onload方法,只会执行一个。
$(document).ready()可以同时编写多个,并且都可以得到执行。
- 简化写法
window.onload没有简化写法。
$(document).ready(function(){})可以简写成$(function(){});
常用标签
1 | <meta charset="utf-8"> |
获取url参数
1 | let reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)") |
String原型方法扩展
1 | // 连字符转驼峰 |
拦截控制台、右键和F12
1 | document.onkeydown = function () { |
崩溃欺骗
1 | var OriginTitle = document.title; |
a标签
1 | // 邮件 |
<script>
元素放在 HTML 文件底部
我们将 <script>
元素放在 HTML 文件底部的原因是,浏览器按照代码在文件中的顺序解析 HTML。如果 JavaScript在最前面被加载,HTML还未加载,JavaScript将无法作用于HTML,所以JavaScript无效,如果 JavaScript 代码出现问题则 HTML 不会被加载。所以将 JavaScript 代码放在底部是最好的选择。当然在当下,并不是说 script 标签必须放在底部,因为你可以给 script 标签添加 defer 或者 async 属性。
某个字符在字符串中的个数
1 | let str="11112234241" |
数组求最大值方法汇总
1 | 1. es6拓展运算符... |
1 | function foo(p1,p2) { |
回到顶部
1 | function goback() { |
手机号处理中间4位替换成*(数据脱敏)
方法1 substr方法
1 | let phone="18883269663" |
方法2 正则匹配分组
1 | let tel = "13122223333"; |
转换树形结构数据
1 | let arr=[{"departmentId":"2807369902638080","departmentName":"四合院大数据有限公司","departmentDesc":"四合院大数据有限公司是非常好的公司","createTime":null,"hasChild":false,"parentId":null},{"departmentId":"2805950137730048","departmentName":"产品策划部","departmentDesc":null,"createTime":null,"hasChild":true,"parentId":null},{"departmentId":"2805949110338560","departmentName":"研发中心","departmentDesc":null,"createTime":null,"hasChild":true,"parentId":null}]; |
浏览器返回上一页
1 | <a href="#" onclick="javascript:history.back(-1);">返回到上一页</a> |
浏览器前进后退
1 | history.forward();//前进 |
去重数组里对象相同值得key
1 | const key = 'id' |
变量声明
1 | (function() { |
with语句
with语句的作用是将代码的作用域设置到一个特定的对象中。
利:with语句可以在不造成性能损失的情况下,减少变量的长度。很多情况下,也可以不使用with语句,而是使用一个临时变量来保存指针,来达到同样的效果。
弊:with语句使得程序在查找该语句块中的所有的变量值时,都是先在该with语句指定的对象下面先寻找一遍,然后再去外面的作用域去寻找。所以尽量不要在该语句块中去使用一些不属于该对象中的变量
用法
1 | var x = { |
相当于
1 | var x = { |
boolean类型在进行比较时会类型转换成number
1 | 11==true // 11==1 false |
RGB到十六进制
使用按位左移运算符(<<)和toString(16),然后padStart(6,’0’)将给定的RGB参数转换为十六进制字符串以获得6位十六进制值。
1 | const rgbToHex = (r, g, b) => ((r << 16) + (g << 8) + b).toString(16).padStart(6, '0'); |
滚动到顶部
使用document.documentElement.scrollTop或document.body.scrollTop获取到顶部的距离。
1 | const scrollToTop = _ => { |
求和
1 | const sum = arr => arr.reduce((acc, val) => acc + val, 0); |
大写每个单词的首字母
使用replace()匹配每个单词的第一个字符,并使用toUpperCase()来将其大写。
1 | const capitalizeEveryWord = str => str.replace(/[a-z]/g, char => char.toUpperCase()); |
计算数组中某值出现的次数
每次遇到数组中的特定值时,使用reduce()来递增计数器。
1 | const countOccurrences = (arr, value) => arr.reduce((a, v) => v === value ? a + 1 : a + 0, 0); |
数组间的区别
从b创建一个Set,然后在a上使用Array.filter(),只保留b中不包含的值。
1 | const difference = (a, b) => { const s = new Set(b); return a.filter(x => !s.has(x)); }; |
阶乘
使用递归。如果n小于或等于1,则返回1。否则返回n和n - 1的阶乘的乘积。
1 | const factorial = n => n <= 1 ? 1 : n * factorial(n - 1); |
获取滚动位置
如果已定义,请使用pageXOffset和pageYOffset,否则使用scrollLeft和scrollTop,可以省略el来使用window的默认值。
1 | const getScrollPos = (el = window) => |
最大公约数
1 | const gcd = (x, y) => !y ? x : gcd(y, x % y); |
UUID生成器
使用crypto API生成符合RFC4122版本4的UUID。
1 | const uuid = _ => |
检查变量是否声明
如果读取一个不存在的键,会返回undefined,而不是报错。可以利用这一点,来检查一个全局变量是否被声明。 前二种写法有漏洞,如果a属性是一个空字符串(或其他对应的布尔值为false的情况),则无法起到检查变量是否声明的作用。 最好的方法是使用in
1 | // 假设变量x未定义 |
使用对象结构代替 switch…case
switch…case不使用大括号,不利于代码形式的统一。此外,这种结构类似于goto语句,容易造成程序流程的混乱,使得代码结构混乱不堪,不符合面向对象编程的原则。
1 | // 反模式 |
隐藏console打印在哪一行的信息
1 | setTimeout(console.log.bind(console, 'Hello world'), 2000) |
手机震动
1 | window.navigator.vibrate(200); // vibrate for 200ms |
[1,2,11]用sort方法进行排序
1 | [1,2,11].sort() // [1,11,2] sort方法默认根据unicode进行排序 |
[1,2,3].map(parseInt)
1 | [1,2,3].map(parseInt) // [1,NaN,NaN] 这里第二个参数是map的index,3对应下标2,3没有二进制的。 |
parseInt第二个参数
可选。表示要解析的数字的基数。该值介于 2 ~ 36 之间。
如果省略该参数或其值为 0,则数字将以 10 为基础来解析。如果它以 “0x” 或 “0X” 开头,将以 16 为基数。
如果该参数小于 2 或者大于 36,则 parseInt() 将返回 NaN。
图片上传
传统的form表单上传
1
2
3<form action="" method="POST" enctype="multipart/form-data">
<input type="file" name="img">
</form>隐藏iframe模拟Ajax上传
1
2
3
4
5
6// form的enctype属性为编码方式,常用有两种:application/x-www-form-urlencoded和multipart/form-data,默认为application/x-www-form-urlencoded。
// multipart/form-data是上传二进制数据;它告诉我们传输的数据要用到多媒体传输协议
<iframe name="ajaxUpload" style="display:none"></iframe>
<form action="url" method="post" enctype="multipart/form-data" target="ajaxUpload">
<input type="file" name="img">
</form>h5 ajax上传
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
46
47// 使用已有的form表单,来实例化FormData对象
var form = document.getElementById('form');
var formData = new FormData(form);
// 可以使用append来添加更多的信息
var img = document.getElementById('img').files[0];
var formData = new FormData();
formData.append('img',img);
// 获取
// formData.get('img') formData.getAll('img') [img]
// 设置修改
// formData.set('img',1) // 已存在则修改,不存在则新增
// 判断是否存在
// formData.has('img')
// 删除
// formData.delete('img')
// 返回迭代器
// formData.entries()
// formData.append("k1", "v1");
// formData.append("k1", "v2");
// formData.append("k2", "v1");
// var i = formData.entries();
// i.next(); // {done:false, value:["k1", "v1"]}
// i.next(); // {done:fase, value:["k1", "v2"]}
// i.next(); // {done:fase, value:["k2", "v1"]}
// i.next(); // {done:true, value:undefined}
// 利用XHR上传图片
var xhr = new XMLHttpRequest();
xhr.open('POST',url);
xhr.onreadystatechange = function(){};
xhr.send(formData);
// 获取上传的进度
xhr.upload.onprogress = function(evt){
console.log(evt);
var loaded = evt.loaded; //已经上传的大小
var total = evt.total;//附件总大小
var per = Math.floor(100 * loaded / total );//已经上传的百分比
}检验图片信息
1
2
3
4
5
6<input type="file" id="img" name="img"/>
// 获取file对象
var img = document.getElementById('img');
var files = img.files;
var file = files[0];
实现JSONP
1 | // 对象存储 |
chrome浏览器拦截多次window.open
1 | // 遍历打开页面 chrome浏览器会拦截只允许一次的请求 这里模拟点击 |
mixed
1 | 1 << 31 // 1* 2^31 |
高度
1 | window.scrollY // 225 |
自适应单位
vw:1vw等于视口宽度的1%。
vh:1vh等于视口高度的1%。
vmin:选取vw和vh中最小的那个。
vmax:选取vw和vh中最大的那个
CSS百分比是相对于包含它的最近的父元素的高度和宽度
dom解绑事件
attachEvent是IE有的方法,它不遵循W3C标准,而其他的主流浏览器如FF等遵循W3C标准的浏览器都使用addEventListener,所以实际开发中需分开处理。
多次绑定后执行的顺序是不一样的,attachEvent是后绑定先执行,addEventListener是先绑定先执行。
为元素解绑事件
注意:用什么方式绑定事件,就应该用对应的方式解绑事件
- 解绑事件
- 对象.on事件名字=事件处理函数—>绑定事件
- 对象.on事件名字=null;
1 | $("btn").onclick=function () { |
- 解绑事件
- 对象.addEventListener(“没有on的事件类型”,命名函数,false);—绑定事件
- 对象.removeEventListener(“没有on的事件类型”,函数名字,false);
1 | $("btn").addEventListener("click",f1,false); |
- 解绑事件(IE)
- 对象.attachEvent(“on事件类型”,命名函数);—绑定事件
- 对象.detachEvent(“on事件类型”,函数名字);
1
2$("btn").attachEvent("onclick",f2);
$("btn").detachEvent("onclick",f1);
位运算符
位运算符一般使用的很少,当他与数字一起使用的时候,比如~N => -(N+1),这个式子仅当 N == -1 的时候结果为0。位运算可以提高程序的运行效率。
我们可以在indexof(…)函数前面加一个~来进行布尔检查,检查一个项是否存在于Array或者string中。
1
2
3
4
5
6
7
8
9
10
11
12
13
14let userName = 'break jerry'
if(~userName.indexOf("break")) {
console.log('access denied');
}else {
console.log('access granted');
}
// 奇偶性
if(index & 1) {
// 1 奇数 odd
}else{
// 0 偶数 even
}
关闭当前页面
- window.close()
- window.open(“about:blank”,”_self”).close();
字节节省写法
1 | //取整 |
简单计算页面FPS
整体思路是一秒有一千毫秒,先记录当前时间作为最后一次记录fps的时间,通过 requestAnimationFrame 回调不断给累加fsp计数器, 并且判断上次记录fps的时间是否达到1000毫秒以上,如果满足条件,就将fps累加器的值作为当前fps显示,并且重置fps累加器。
1 | var showFPS = (function () { |
你不知道的new.target
new 是构造函数生成实例的命令, ES6为 new 命令引入了 new.target属性。这个属性用于确定构造函数是怎么调用的。 用法:在构造函数中, 如果一个构造函数不是通过 new操作符调用的, new.target会返回 undefined。
使用场景:
es5写法
如果一个构造函数不通过 new 命令生成实例, 就报错提醒。
1
2
3
4
5
6
7
8
9
10
11 function Shape(options) {
if (this instanceof Shape) {
this.options = options
} else {
// 要么手动给它创建一个实例并返回
// return new Shape(options)
// 要么提醒
throw new Error('Shape 构造函数必须使用 new 操作符')
}
}
es6写法
子类继承父类, 那么父类构造函数中的 new.target 是子类构造函数的名称。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 class Zoo {
constructor() {
if (new.target === Zoo) throw new Error('Zoo构造函数只能用于子类继承')
}
}
const zoo = new Zoo() // 报错
class Dog extends Zoo {
constructor() {
super()
}
}
const dog = new Dog() // 不报错
文件扩展名
1 | var filePath = '21312321.mp3' |
blur和click冲突
场景:平时做表单验证的时候一般都有个input框和删除按钮,然后习惯性在失去焦点的时候> 去验证输入的内容是否正确,做验证,发请求等等。 这个时候,那个点击删除按钮往往也就触发了input的失去焦点事件
- 给失去焦点的时间加上延迟时间,让blur时间在click事件后执行,这个方法固然能够解决问题,但是本人并不是很推荐,因为影响性能,不到最后不用这个方法;
- event.relatedTarget.id事件属性返回与事件的目标节点相关的节点。(非IE)
- mousedown事件替代处理click事件
object标签
object标签不在dom文档流里面,浏览器在解析的时候先把object放置在最上层,然后依次解析dom文档,放在下层。
如果这样引用多媒体文件推荐还是不使用object,只有iframe的层级在它之上处理起来很麻烦。
escape、encodeURI、encodeURIComponent区别
- escape是对字符串进行编码,对URL使用不需要 encodeURI encodeURIComponent
- encodeURI方法不会对下列字符编码 ASCII字母、数字、!@#$&*()=:/,;?+’
- encodeURIComponent方法不会对下列字符编码 ASCII字母、数字、!*()’ 所以encodeURIComponent比encodeURI编码的范围更大。 实际例子来说,encodeURIComponent会把 http:// 编码成 http%3A%2F%2F 而encodeURI却不会。 当编码url时需要使用encodeURI,当需要编码参数时使用encodeURIComponent
链式调用
1 | 1.方法体内返回对象实例自身(this) |
setTimeout 为不可执行的字符串时会造成内存泄漏
1 | setTimeout("fn()",100) |
JSON.parse和JSON.stringify其他参数
1 | var obj ={name:'cosyer',age:15} |
随机数
1 | // [0,1) 左闭右开 min-max |
chrome浏览器跳转调试
问题描述:在chrome里调试接口的时候发现页面跳转之后会看不到之前的接口返回,即使你将Perserve log 勾上,能看到跳转之前的接口,但是看不到返回的内容
问题解决:查了一些资料,chrome之所以这么做(看不到跳转之前的接口返回)是为了节省内存开销,但是这个给调试带来了困难,然后我参照stackoverflow的解决方案, 在控制台执行 window.onunload = function() { debugger; } 为了在页面unload之前进入debug,但是尝试了还是看不到跳转之前接口返回的内容,最后的解决方案是用firefix调试,在火狐里在调试中的网络中勾选持续日志可以看到跳转之前的接口,且可以看到接口返回内容。
参考资料
时间
UTC:世界协调时间,是经过平均太阳时(以格林威治时间GMT为准)、地轴运动修
正后的新时标以及以秒为单位的国际原子时所综合精算而成的时间。UTC比GMT更
加精准,其误差值必须保持在0.9秒以内。若大于0.9秒,则由位于巴黎的国际地
球自转事务中央局发布闰秒,使UTC与地球自转周期一致,所以基本上UTC的本质
强调的是比GMT更为精确的世界时间标准。
GMT:格林尼治是位于英国南郊的原格林尼治天文台所在地,也是地理经度的起
始点。这里所设定的时间就叫格林尼治时间,也是世界时间参考点,全世界都根
据时区的不同以格林尼治的时间作为标准来设定时间。
夏令时:因为夏天白天时间比较长,太阳会比较早出现,某些地区就将当地的时
间提早一段时间(例如一小时),以达到利用阳光节约能源的目的。 通常秋季
时,此地区会将当地时间推后一段时间(例如一小时),回复正常时间。
UTC和本地时间的关系:本地时间=UTC+时区+夏令时偏移量。
uuid生成(Math.random)
1 | function uuid(len, radix) { |
1 | function generateDynamic32UUID() { |
1 | // hash name |
UUID(createObjectURL)
1 | function uuid() { |
jq原生对照
1 | 1、元素获取 |
实现复制tiny
1 | // 复制连接地址 |
scrollbar滚动条样式优化
1 | ::-webkit-scrollbar-corner { |
内网ip段
内网段10.0.0.0—10.255.255.255,172.16.0.0—172.31.255.255,192.168.0.0—192.168.255.255
获取当前鼠标坐标
1 | var getCoordInDocumentExample = function () { |
类数组对象转数组
1 | function func(){ |
页面滚动条到底判断
1 | //获取网页的总高度,主要是考虑兼容性所以把Ie支持的documentElement也写了,这个方法至少支持IE8 |
1 | 网页可见区域宽: document.body.clientWidth; |
yield函数
1 | // 传入匿名函数 |
复制添加版权申明
1 | if (window.clipboardData) { |
包版本号
一个包的版本号基本由三位数字构成 x.x.x, 它们分别是主版本号, 次版本号, 修订号。
- *: 升级主版本号 + 次版本号 + 修订号;
- ^: 升级次版本号 + 修订号;
- ~: 升级修订号;
npm使用 a.b.c 的版本号来管理安装包,a大达版本号,有重大api改变,一般不向下兼容,b为小版本号,新增功能,向下兼容,c为补丁号,通常修复一些bug。
script标签关键字
- defer 并发下载 顺序执行 渲染完再执行(延迟执行)
- async 异步下载 异步执行谁先下载完 谁先执行
防止对象篡改
- Object.preventExtensions(obj): obj 不能添加属性
- Object.seal(obj): obj 不能添加/删除属性
- Object.freeze(obj): obj 不能添加/删除/修改属性
Object.freeze工作方式与Object.preventExtensions相同,并且它使所有对象的属性不可写且不可配置。 唯一的缺点是Object.freeze
仅适用于对象的第一级:嵌套对象不受操作的影响。
module.exports和exports
module.exports才是真正的接口,exports只不过是它的一个辅助工具。 最终返回给调用的是module.exports而不是exports。 所有的exports收集到的属性和方法,都赋值给了module.exports。当然,这有个前提,就是module.exports本身不具备任何属性和方法。
最好分别定义module.exports和exports
建议导出对象用module.exports,导出多个方法和变量用exports
meta自动跳转
1 | <meta http-equiv="Refresh" content="1; url=http://www.baidu.com"/> |
前端生成文件并下载
Blob对象简要介绍
Blob 对象表示一个不可变、原始数据的类文件对象。Blob 表示的不一定是JavaScript原生格式的数据。File 接口基于Blob,继承了 Blob 的功能并将其扩展使其支持用户系统上的文件。生成Blob对象有两种方法:一种是使用Blob构造函数,另一种是对现有的Blob对象使用slice方法切出一部分。
const aBlob = new Blob( array, options ); 参数说明
- array 是一个由ArrayBuffer, ArrayBufferView, Blob, DOMString 等对象构成的 Array ,或者其他类似对象的混合体,它将会被放进 Blob。DOMStrings会被编码为UTF-8。
- options 是一个可选的BlobPropertyBag字典,它可能会指定如下两个属性: type,默认值为 “”,它代表了将会被放入到blob中的数组内容的MIME类型。 endings,默认值为”transparent”,用于指定包含行结束符\n的字符串如何被写入。 它是以下两个值中的一个: “native”,代表行结束符会被更改为适合宿主操作系统文件系统的换行符,或者 “transparent”,代表会保持blob中保存的结束符不变
1 | // const debug = {hello: "world"}; |
防止frame嵌套
1 | if(top != self){ |
取反运算简化indexOf判断
1 | if(~[1,2,3].indexOf(1)){ |
已知年月,求当月多少天
- 先判断该年份是否是闰年,来处理 2 月份情况,闰年 2 月共 29 天,非闰年 2 月共 28 天
- 再判断其他月份,如 1 月共 31 天,4 月共 30 天
更简便的方法
1
2
3
4
5
6
7
8
9// Date API 处理日期溢出时,会自动往后推延响应时间
function getMonthCountDay (year, month) {
return 32 - new Date(year, month-1, 32).getDate();
// 32 - (32-当月天数) = 当月天数
}
// better
function getMonthCountDay (year, month) {
return new Date(year, month , 0).getDate();
}
日期格式转化 2019/3/19 => 2019-3-19
正则
1
2let date = new Date()
let dateStr = date.toLocaleDateString().replace(/\//g,'-')数组计算
1
2
3
4
5
6let date = new Date()
let arr = date.toLocaleDateString().split('/')
arr = arr.map((item) => {
return parseInt(item) < 10 ? '0' + item : item
})
let dateStr = arr.join('-')
求数值的n次幂
1 | Math.pow(2,10); //1024 |
分号的重要性
1 | const luke = {} |
前端h5 download属性下载文件(appendChild兼容firefox)
1 | function downFile(content, filename) { |
1 | // 模拟点击 a 链接 |
禁止滚动条滚动
1 | var keys = [37, 38, 39, 40]; |
map等遍历注意事项
1 | var it = [] |
符合密码学要求的随机值
1 | function getRandomNumbers(min, max) { |
字符串反转
如果需要支持UTF-16或其他多字节字符的解决方案,请注意此函数将给出无效的Unicode字符串或看起来很有趣的有效字符串。需要注意
1 | function reverse(str) { |
delete varible
1 | delete xxx // true |
jquery指定元素滚动到视图中间
1 | function scrollToViewCenter($element) { |
new Array()
1 | var myArray = Array(); |
构造函数scope-safe模式
1 | function Book(name){ |
jquery设置!important
1 | $("#container").css("top"); |
:empty 选择器区分样式
:empty 选择器匹配没有子元素(包括文本节点)的每个元素。
这里举个小红点的例子:
如图所示,小红点有内容以及无内容的样式差异,按照常规的处理方式,我们一般是通过类名区分,但是我们可以简单通过:empty选择器区分开。
1
<div class="jd"><i>3</i></div>
1 | .jd i:empty { |
arr.reduce(callback[, initialValue])
- reduce接受两个参数, 一个回调, 一个初始值
- 回调函数接受四个参数 previousValue, currentValue, currentIndex, array
第一个表达式等价于 Math.pow(3, 2) => 9; Math.pow(9, 1) =>9
第二个表达式异常 Uncaught TypeError: Reduce of empty array with no initial value
变量提升
在 JavaScript中, functions 和 variables 会被提升。变量提升是JavaScript将声明移至作用域 scope (全局域或者当前函数作用域) 顶部的行为。
1
2
3
4
5
6
7
8
9
10var name = 'World!';
(function () {
if (typeof name === 'undefined') {
var name = 'Jack';
console.log('Goodbye ' + name);
} else {
console.log('Hello ' + name);
}
})();
// Goodbye Jack
最大安全数 + 1值没有变化 会导致循环
1 | var END = Math.pow(2, 53); |
稀疏数组
没有内容的数组, array 上的操作会跳过这些未初始化的’坑’.
1
2
3
4
5
6
7
8
9var ary = [0,1,2];
ary[10] = 10;
ary.filter(function(x) { return x === undefined;});
// []
var ary = Array(3);
ary[0]=2
ary.map(function(elem) { return '1'; });
// ["1", undefined × 2]
一个鲜为人知的实事: Array.prototype => []
1 | Array.isArray( Array.prototype ) |
arguments在es6有初始值时不同
1 | function sidEffecting(ary) { |
reverse返回调用者
1 | var x = [].reverse; |
Number.MIN_VALUE > 0
1 | Number.MIN_VALUE > 0 |
抽象相等
1 | var a = [0]; |
隐式类型转换
1 | -、*、/、% :一律转换成数值后计算 |
1 | [1 < 2 < 3, 3 < 2 < 1] |
number + .
1 | 3.toString() // error (3).toString() |
automatic global
1 | (function(){ |
regexp expression
1 | var a = /123/, |
function name is readonly
1 | function foo() { } |
parseInt 坑
1 | "1 2 3".replace(/\d/g, parseInt) |
function prototype
1 | function f() {} |
regexp translate
1 | var lowerCaseOnly = /^[a-z]+$/; |
[,,,].join(“, “)
1 | [,,,].join(", ") |
function length
1 | var a = Function.length, |
Date equal
1 | var a = Date(0); |
function scope param
1 | function foo(a) { |
nodejs Event模块的简单实现
1 | function Event() { |
实现超链接显示A网站实际跳转B网站
1 | <a href="//www.tmall.com" onclick="host='jd.com'">tmall</a> |
nodejs 恶作剧:给系统创建一个叫 node_modules 的用户,然后 npm install 就无法使用了
最简单的方式实现console.log(1)
返回0
1 | console = Math; |
如何将整个网站页面变成黑白色?(灰阶)
对于一些需要悼念的日子,很多人也都想把自己的网站弄成全站黑白来表示自己的哀悼之情。还有其他特殊原因(比如公祭日)对部分事件表示哀悼,所以需要把整个网站设置为灰色或者黑白方格。
1 | html { |
filter 是滤镜的意思,filter:gray 的意思就是说给页面加上一个灰度的滤镜,所以 html 里面的所有内容都会变成黑白的了。
文字模糊
1 | color: transparent; |
毛玻璃
1 | .blur { |
多重边框
1 | div { |
黑幕效果
1 | .heimu, .heimu a, a .heimu, .heimu a.new { |
太对了哥,哥太对
字符串和base64相互转换(编码、解码)
1 | // 字符串转base64 |
1 | echo test|base64 #加密 |
随机名称
1 | function getRandomName() { |
IDEA连接Github时出现:Failed to connect to github.com port 443: Connection refused的解决方法
本地hosts文件中配置不正确导致的。
1 | git config --global http.proxy http://127.0.0.1:1080 |
但创建完仓库后 push 不上去,这个时候就需要取消代理
1
2
3git config --global --unset http.proxy
git config --global --unset https.proxy
counter
1 | <script async src="https://busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script> |
i18n语料替换
1 | function i18nReplace(s, o) { |
一行代码实现简单模版引擎
1 | function template(tpl, data) { |
快速生成包含26个字母的数组
1 | Array.from({length: 26}, (_, i) => String.fromCharCode(65 + i)); |
单行文本的省略号
1 | .single-ellipsis{ |
多行元素的文本省略号
1 | .multiline-ellipsis { |
如何实现sleep效果
while
1 | function sleep(ms) { |
promise
1 | function sleep(ms) { |
generate
1 | function* sleep(ms){ |
async/await
1 | function sleep(ms){ |
实现一些主流框架的循环渲染
问题
1 | var items = [ |
1 | var items = [ |
思考:如何实现 npm install ?
假如老板给你 一个 npm 包的列表 ,要你找出这些 npm 包的所有依赖包名,简述一下实现思路
对包和包的依赖列表进行缓存 -> A 和 B 都依赖了 C,从 A 分析一次后,B 还需要再分析吗?
使用并发,但要控制并发量 -> 一个包一个包的查会不会太慢?请求这么频繁 npm 会不会封你的 ip
找依赖的时候使用循环,而不是递归 -> 如果一个包的依赖非常非常复杂,内存爆了怎么办 具有失败重试和离线缓存 -> 中途网络挂掉怎么处理?失败的一直失败怎么办?
Github无法访问 hosts 配置
1 | GitHub Start |
修改方法:
Windows: 修改文件 C:/Windows/system32/drivers/etc/hosts
Linux系: 修改文件 /etc/hosts
Android: 修改文件 /system/etc/hosts (需要Root)
保留两位小数
toFixed()方法
1
2
3var num =2.446242342;
num = num.toFixed(2);
console.log(num); //2.45Math.floor()
1
2num = Math.floor(num * 100) / 100;
console.log(num); //2.44字符串匹配
1
2num = Number(num.toString().match(/^\d+(?:\.\d{0,2})?/));
console.log(num); //2.44保留两位小数 浮点数四舍五入 位数不够 不补0
1
2
3
4function fomatFloat(src,pos){
return Math.round(src*Math.pow(10, pos))/Math.pow(10, pos);
}
console.log(fomatFloat(3.12645,2)); // 3.13
H5 语音合成 SpeechSynthesisUtterance API
1 | var utterance = new SpeechSynthesisUtterance('cosyer'); |
JS实现语音播报
1 | function speckText(str){ |
instanceof测试练习
1 | Object instanceof Function |
掘金头像旋转
1 | #pic:hover { |
- transform: rotate(666turn); 常见的用来旋转元素角度的css,这里用到的是turn,1turn = 360°
- transition-delay:1s; 这个属性的作用就是效果执行前的等待时间
- transition-property: all; 这个属性是指明效果变换的位置,比如width,height等,all是所有属性。
- transition-duration: 59s; 过渡效果的持续时间。
- transition-timing-function: cubic-bezier(.34,0,.84,1); 过渡效果的速度曲线 四个值的范围都是0-1 代表整个过程。
时间轴
1 | <div class="timeline-content"> |
1 | /** 时间轴 */ |
卡券效果
1 | .coupon{ |
css禁用鼠标事件
1 | .disabled { |
css禁止用户选择
1 | body{ |
jquery添加扩展方法
1 | $.fn.stringifyArray = function(array) { |
- jquery.extend 与 jquery.fn.extend的区别?
jquery.extend 为jquery类添加类方法,可以理解为添加静态方法 源码中jquery.fn = jquery.prototype所以jquery.fn.extend扩展,所有jquery实例都可以直接调用。
1 | // 多个事件同一个函数: |
万物转换(o゚▽゚)o
1 | 'vue'.split('').sort().join('') // euv |
require.context实现自动化导入
一个webpack的api,通过执行require.context函数获取一个特定的上下文,主要用来实现自动化导入模块,在前端工程中,如果遇到从一个文件夹引入很多模块的情况,可以使用这个api,它会遍历文件夹中的指定文件,然后自动导入,使得不需要每次显式的调用import导入模块
require.context函数接受三个参数
directory {String} -读取文件的路径
useSubdirectories {Boolean} -是否遍历文件的子目录
regExp {RegExp} -匹配文件的正则
1 | // 遍历当前目录下的test文件夹的所有.test.js结尾的文件,不遍历子目录 |
1 | // 简化vuex module index.js |
img标签之间的间距问题原理
众所周知,多个img并列显示时会有几像素间距,但是这并不是img标签特有的特性。
原理
实际上,所有display属性为inline , inline-block 的盒模型都会有文字特性,间距就是由于两个标签之间的空白引起的。
常用方案
删除标签之间的空格
1
<img src="img/test.jpg" alt=""><img src="img/test.jpg" alt=""><img src="img/test.jpg" alt="">
将父级设置为font-size: 0px:
1
2
3
4
5
6
7<div style="font-size: 0px">
<img src="img/test.jpg" alt="">
<img src="img/test.jpg" alt="">
<img src="img/test.jpg" alt="">
<img src="img/test.jpg" alt="">
<img src="img/test.jpg" alt="">
</div>将父级设置为使用负margin去除边距
1
2
3img {
margin-left: -8px;
}设置浮动
1
2
3img {
float: left;
}
prettier script
1 | "jsformat": "prettier --write \"./**/*.js\"" |
HTML - 输入框 Input 按回车 Enter 自动刷新页面解决方案
原因
在一个 form 表单中,若只有一个 input,按回车键表单会自动提交,但是当表单中存在多个 input 时,按回车键不会执行任何操作,这是 form 表单的一个特性。
解决
直接去除掉 form 表单,当然这是最简单粗暴的方法。
如果一个 input 会自动提交,那么比较容易想到的是再加一个 input。值得注意的是 这里的 input 不能设置 type 为 hidden,这样一样是不生效的,form 一样会认为只有一个 input。需要设置成 。
给 input 加上回车事件直接 return false。在 input 加上 οnkeydοwn=”if(event.keyCode==13){return false;} 。
直接阻止 form 表单的提交,在 form 表单加入 οnsubmit=”return false;”。
为什么ES模块比CommonJS更好?
ES模块是官方标准,也是JavaScript语言明确的发展方向,而CommonJS模块是一种特殊的传统格式,在ES模块被提出之前做为暂时的解决方案。 ES模块允许进行静态分析,从而实现像 tree-shaking 的优化,并提供诸如循环引用和动态绑定等高级功能。
什么是 tree-shaking
(树摇)
Tree-shaking, 也被称为 “live code inclusion,” 通常用于打包时移除js中未引用的代码(dead-code),它依赖于ES6模块系统中的import 和 export 的静态结构特性
虽然生产模式下默认开启,但是由于经过babel编译全部模块被封装成IIFE
IIFE存在副作用无法被tree-shaking掉,需要配置 { module: false } 和 sideEffects: false
rollup和webpack的shaking程度不同,以一个class为例子
scope hoisting
Scope hositing 作用:是将模块之间的关系进行结果推测,可以让webpack文件打包出来的代码文件更小、运行的更快 scope hositing实现原理:分析出模块之间的依赖关系,尽可能的把打散的模块合并到一个函数中,但是前提是不能造成代码冗余, 因此只有哪些被引用了一次的模块可能被合并 由于scope hositing 需要分析出模块之间的依赖关系,因此源码必须使用ES6模块化语句,不然就不能生效,原因和 tree shaking一样。
webpack优化
production模式自带优化
- tree shaking
- scope hoisting
- 代码压缩混淆(UglifyJsPlugin)
- 图片压缩: imagemin、image-webpack-loader
css优化
- css提取到独立文件(mini-css-extract-plugin)
- postcss添加前缀
- css压缩(optimize-css-assets-webpack-plugin)
js优化
- 代码分离(code splitting)
- 入口起点:使用entry配置,手动的分离代码(配置多入口)
1
2
3
4entry:{
main: './src/main.js',
other: './src/other.js'
}, - 放置重复:使用 SplitChunksPlugin 去重和分离 chunk(抽取公共代码)
1
2
3
4
5optimization:{
splitChunks:{
chunks: "all"
}
} - 动态导入:通过模块的内联函数调用来分离代码(懒加载) webpack4默认是允许import语法动态导入的,但是需要babel的插件支持,最新版babel的插件包为:@babel/plugin-syntax-dynamic-import,需要注意动态 导入最大的好处就是实现了懒加载,用到那个模块才会加载那个模块,可以提高SPA应用程序的首屏加载速度,三大框架的路由懒加载原理一样。
noParse(缩小文件搜索范围)
在引入一些第三方模块时,如jq等,我们知道其内部肯定不会依赖其他模块,因为我们用到的只是一个单独的js或者css文件,所以此时如果webpack再去解析他们的内部依赖关系,其实是非常浪费时间的,就需要阻
止webpack浪费精力去解析这些明知道没有依赖的库,可以在webpack的配置文件的module节点下加上noParse,并配置正则来确定不需要解析依赖关系的模块
1
2
3module:{
noParse: /jquery|bootstrap/ // jquery|bootstrap 之间不能加空格变成 jquery | bootstrap, 会无效
}
- 通过 include 和 exclude 缩小命中范围
- 优化 resolve.modules 配置,指明存放第三方模块的绝对路径,减少寻找时间。
- 优化 resolve.alias/extensions配置
DLLPlugin、DllReferencePlugin(预编译资源模块提高打包速度)
在引入一些第三方模块时,例如Vue、React等,这些框架的文件一般都是不会修改的,而每次打包都需要去解析他们,也会影响打包速度,就算是做了拆分,也只是提高了上线后的用户访问速度,并不会提高构建速度,所以如果需要提高构建速度,应该使用动态链接库的方式,类似windows的dll文件借助DLLPlugin插件实现将这些框架作为一个个的动态链接库,只构建一次,以后的每次构建都只会生成自己的业务代码,可以很好的提高构建效率。
将库和项目代码分离打包需要 dll 映射文件
主要思想在于,将一些不做修改的依赖文件,提前打包,这样我们开发代码发布的时候就不需要再对这些代码进行打包,从而节省了打包时间,主要使用两个插件: DLLPlugin和DLLReferencePlugin 需要注意的是,若是使用的DLLPlugin,CleanWebpackPlugin插件会存在冲突,需要移除CleanWebpackPlugin插件
配置缓存(提高打包速度,插件自带 babel-loader开启,不支持的可以用 cache-loader)
使用 HappyPack 开启多进程 Loader 转换(webpack4推荐thread-loader)
1 | rules: [ |
1 | rules: [ |
使用 include 或 exclude 加快文件查找速度
IgnorePlugin
在引入一些第三方模块时,例如momentJS、dayJS,其内部会做i18n处理,所以会包含很多语言包,而语言包打包时会比较占用空间,如果项目只需要用到中文或者少数语言,可以忽略掉所有的语言包,然后按需引 入语言包,从而使得构建效率更高,打包生成的文件更小
分析优化
在打包时,合理使用插件speed-measure-webpack-plugin和webpack-bundle-analyzer,可以对项目构建过程中的每个loader、plugin等进行耗时统计,并针对耗时的操作进行优化,打包结果可以进行体积的大 小的控制和优化。
windows更新计算机策略
1 | gpupdate /force |
有一个数字字符串,它所代表的数字远大于js所能表示的最大数,可能有两万位,这样的数字你怎么判断它能不能被6整除
- 调接口放到后台处理
最后一位被2整除 && 所有位加起来被3整除
1
2
3
4function isValid(str) {
const arr = str.split('')
return Number(arr[arr.length -1]) %2 === 0 && arr.reduce((total, num) => total + num, 0) % 3 === 0
}高位判断 最大安全数 2**53 -1 // 9007199254740991 因为js用的是IEEE754标准,小数有效位为52位,加上默认的1一共是53位,超过这个就无法保持精确了。
1
2
3
4
5
6
7
8
9
10
11
12
13function isValid(str) {
const arr = str.split('')
let temp = 0
for (let i of arr) {
temp = i * temp + parseInt(i , 10)
temp = temp % 6
}
if (temp === 0) {
return true
} else {
return false
}
}
什么时候适合使用 Map 而不是 Object
「Map」映射是一种经典的数据结构类型,其中数据以 「key/value」 的键值对形式存在 ||Map|Object| |:–|:–:|–:| |默认值|默认不包含任何值,只包含显式插入的键|一个 Object 有一个原型,原型上的键名有可能和自己对象上设置的键名冲突| |类型|任意|String 或 Symbol| |长度|键值对个数通过 size 属性获取|键值对个数只能手动计算| |性能|频繁增删键值对的场景下表现更好|频繁添加和删除键值对的场景下未作出优化|
「Map」 是可迭代的,可以直接进行迭代,例如forEach循环或者for…of…循环
遍历Object
1 | for(const key of Object.keys(object)) { |
JS中的宿主对象与原生对象有何不同?
宿主对象:这些是运行环境提供的对象。这意味着它们在不同的环境下是不同的。例如,浏览器包含像windows这样的对象,但是Node.js环境提供像Node List这样的 对象。
原生对象:这些是JS中的内置对象。它们也被称为全局对象,因为如果使用JS,内置对象不受是运行环境影响。
maven配置环境变量
path配置需要具体的路径
个人使用觉得最好的word转pdf在线网站
knife4j 增强swagger的UI
正则就是有限的状态机
mysql迁移postgresql问题记录:
jdbc连接字符串需要指定当前schema jdbc:postgresql://193.160.26.65:5432/engine?useUnicode=true&characterEncoding=utf-8¤tSchema=faker_vmware
postgresql列名是区分大小写的,大写的列名需要加上双引号
mysql没有bool数据类型,用的tinyint(1),sql语句中where flag = false迁移报错,pg用的int(2)
ON DUPLICATE KEY UPDATE 重复插入约束 => on conflict (id) do update set
在pg中的sql,单引号用来标识实际的值,双引号用来标识表名(table name)或列名(column name)等数据库中存在的值
Typed Arrays
一个TypedArray 对象描述一个底层的二进制数据缓存区的一个类似数组(array-like)视图
markdown github stats
微信分享 hash 路由填坑记录
1 | encodeURIComponent(window.location.href.split('#')[0]) |
Promise题目
1 | Promise.resolve(1).then(2).then(Promise.resolve(3)).then(console.log) |
mock总结
json-server
mock文件夹配置db.json
1
2
3
4{
"rankList": []
}
// 访问localhost:port/api/rankList
点击input事件触发的顺序
1 | const text = document.getElementById('text'); |
计算页面停留时间
- websocket,前端开个长连接,后台统计长连接时间。
- ajax轮询,隔几秒发一个查询,后台记录第一与最后一个查询间隔时间。
- 关闭窗口或者跳转的时候会触发window.onbeforeunload函数,可以在该函数中做处理(有兼容性问题);统计完数据记录到本地cookies中,一段时间后统一发送
二维码如何工作
- pc端随机生成一个含有唯一uid的二维码,并与服务器建立一个长连接;
- 手机扫描二维码,解析出二维码中的uid,并把这个uid和手机端的用户密码进行绑定,上传给服务器;
- 服务器获得客户端信息之后,pc端的长连接轮询操作会获得该消息,显示该账号的信息;
- pc端会再开一个长连接与手机端保持通信,等待手机端确认登陆后,获得服务器授权的token,就可以在pc端登陆进行正常通信了
兼容性查看
可以到Can I use上去查看,官网地址为:caniuse.com
github访问量计数
https://profile-counter.glitch.me/cosyer/count.svg
1
2
3<p align="center"> Visitor count </p>
<img src="https://profile-counter.glitch.me/cosyer/count.svg" />
</a>
github profile统计
1 | <img src="https://github-profile-trophy.vercel.app/?username=cosyer&theme=flat&column=3&margin-w=10&title=Stars,Commit,Issues" alt="logo" height="160" align="center" /> |
simple-icons
github emoji
github badge
萌萌计数器
手动触发event
1 | // 阻塞视图渲染会引发高度错误 |
状态判断简化
1 | v-if="scope.row.reason === 'Error' || scope.row.reason === 'Completed'" |
多个tab页监听localstorage变化
1 | // 非己页面 |
mac启动台没有应用程序图标
1 | mv ~/L*/Application\ Support/Dock/*.db ~/Desktop; killall Dock; exit; |
nodejs JavaScript heap out of memory
默认nodejs 使用的V8引擎官方默认配置是在64位的系统重视1.4g的内存,并且内存大小最大为4g,官方还建议如果使用较 大内存的话则需要分成多个子worker这样来规避大内存的使用。
–max_old_space_size=4096 这个参数,设置最大4gb的内存
全局直接安装 一个npm包
increase-memory-limit
这个包会自动为命令增加 –max_old_space_size=4096 参数
安装increase-memory-limit
导致git commit失败解决方案:删除node_modules->.bin->lint-staged 里面的–max-old-space-size=XXX
https://github.com/endel/increase-memory-limit/issues/30
- export NODE_OPTIONS=–max_old_space_size=4096
超链接 target=”_blank” 要增加 rel=”noopener noreferrer”
当你浏览一个页面点击一个a标签连接 跳转到另一个页面时,
在新打开的页面(baidu)中可以通过 window.opener获取到源页面的部分控制权, 即使新打开的页面是跨域的也照样可以(例如 location 就不存在 跨域问题)。
在chrome 49+,Opera 36+,打开添加了rel=noopener的链接, window.opener 会为null。在老的浏览器中,可以使用 rel=noreferrer 禁用
HTTP头部的Referer属性,使用下面JavaScript代替target=’_blank’ 的解决此问题:
1
2
3var otherWindow = window.open('https://mydearest.cn');
otherWindow.opener = null;
otherWindow.location = url;
query参数里含有#需要encode
获取当天0点时间戳
1 | new Date(new Date().toLocaleDateString().replace(/\//g, '-')) |
秒转换
1 | // 秒转换成day、hour、minutes、seconds |
文本区域textarea出现滚动条
1 | <!-- 此时除非遇到换行符,否则内容将一直向右 --> |
case 里let声明
Unexpected lexical declaration in case block no-case-declarations
1 | // 要求case 加上{} |
every数组为空时返回true
1 | [].every(i => i === 1); // true |
判断base64
1 | isBase64(str){ |
带分隔线的button
1 | .pl-textbtn { |
mysql varchar字段过长被截断
mysql在配置文件my.cnf中有一个配置项 [mysqld] sql-mode = “xx_mode” sql-mode中有STRICT_TRANS_TABLES是在数据超长的情况下会插入失败,当删除这个限制时,插入超长会MySQL会 自动截断超长的字段
浏览器发送通知
1 | function notifyMe() { |
文件大小转化
1 | function binaryFormatter(input) { |
每隔12个字符插入换行符
1 | ''.replace(/.{12}/gm,"$&\r\n") |
修复移动硬盘
1 | chkdsk F: /f |
解决 primordials is not defined 问题
在安装npm依赖的时候碰到了ReferenceError: primordials is not defined的问题 原因
安装gulp版本与node版本不兼容
stackoverflow给出的方法是回退node版本或升级gulp版本
mac查看主机ip
1 | ifconfig | grep "inet" |