js常使用的工具函数
序列号格式化输出
1 | /** |
查找数组中是否存在某个属性值,存在就返回
1 | /** |
jQuery如何扩展自定义方法
1 | (jQuery.fn.myMethod=function () { |
冒泡排序
1 | /** |
判断一个字符串中出现次数最多的字符,统计这个次数
1 | let str = 'asdfssaaasasasasaa'; |
去掉一个数组的重复元素
- 计数排序变形
- 使用 Set
- 使用 WeakMap
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16// 方法1
let arr = [2, 3, 4, 4, 5, 2, 3, 6];
function getNewArr(arr) {
let newArr = [];
for (let i = 0; i < arr.length; i++) {
if (newArr.indexOf(arr[i]) < 0) {
newArr.push(arr[i]);
};
};
console.log('新的数组' + newArr);
}
getNewArr(arr);
// 方法2
let newArr = arr.filter(function(ele, index, self) {
return self.indexOf(ele) === index;
});
去除字符串前后的空格
1 | String.prototype.trim = function() { |
判断一个数字是不是整数
1 | function isInt(num) { |
获取浏览器的地址参数
1 | function getUrlParams(url) { |
JS递归算法1+ 2+3…..100的和
1 | function num(n) { |
找出一组数据中的奇数和偶数,偶数乘以2,并从小到大排列,奇数从大到小排列,最后合并数组
1 | var arr = [4, 3, 8, 6, 2, 9, 1]; |
根据json对象的某一属性对其进行排序
https://www.cnblogs.com/ygtq-island/p/6512728.html
1 | var json = { |
js返回两个数组的差异值
1 | // 普通算法 |
某年某月的1号为星期几
1 | var weekDay = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']; |
数据的排序 123454321 23456765432
1 | // 方法1 |
首字母大写
1 | /** |
深拷贝
- 递归
- 判断类型
- 检查环(也叫循环引用)
- 需要忽略原型
理解深浅拷贝,需了解
- 基本类型–名值存储在栈内存中,例如let a=1
- 引用数据类型–名存在栈内存中,值存在于堆内存中,但是栈内存会提供一个引用的地址指向堆内存中的值
1
2
3
4
5
6
7
8
9
10
11
12
13
14function deepCopy(obj) {
// 判断是否是简单数据类型,
if (typeof obj == 'object') {
//复杂数据类型
var result = obj.constructor == Array ? [] : {};
for(let i in obj) {
result[i] = typeof obj[i] == 'object' ? deepCopy(obj[i]) : obj[i];
}
} else {
//简单数据类型 直接 == 赋值
var result = obj;
}
return result;
}
将类数组转化为数组
1 | function trigger() { |
使用 Array的 slice 进行数组复制( 浅复制)
1 | var items = [1, 2, 3]; |
使用 for-in 循环时需要避免对象从原型链上继承来的属性也被遍历出来,因此保险的做法是对 key 是否是对象自身的属性进行验证
1 | // good |
if(a === 1 || a === 2 || a === 3){}推荐写法
1 | [1, 2, 3].indexOf() || /^(1|2|3)$/.test() |
三位数字分离与合并的相互转化
1 | function numSplit(val) { |
抽离出相同类型的数据
1 | // es6 |
1 | let _typeArr = []; // 枢纽展示类型 |
1 | // es5的处理 |
函数防抖和函数节流
节流(一段时间执行一次之后,就不执行第二次)
注意 认为节流函数不是立刻执行的,而是在冷却时间末尾执行的(相当于施法有吟唱时间),那样说也是对的。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15function throttle(fn, delay) {
let canUse = true;
return function() {
if (canUse) {
fn.apply(this, arguments);
canUse = false;
setTimeout(() => {
canUse = true;
}, delay)
}
}
}
const throttled = throttle(() => console.log('hi'));
throttled();
throttled();防抖(一段时间会等,然后带着一起做了)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16function debounce(fn, delay) {
let timerId = null;
return function() {
const context = this;
if (timerId) {
window.clearTimeout(timerId);
}
timerId = setTimeout(() => {
fn.apply(context, arguments);
timerId = null;
}, delay)
}
}
const debounced = debounce( () => console.log('hi'))
debounced()
debounced()
手写AJAX
1 | var request = new XMLHttpRequest(); |
事件委托
1 | // 简单版本 |
用 mouse 事件写一个可拖曳的 div
快速看到效果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
28var dragFlag = false;
var position = null;
drag.addEventListener('mousedown', function(e) {
dragFlag = true;
position = [e.clientX, e.clientY];
})
// mousemove 与 mouseup 不能监听在元素上 快速拖到会有问题
document.addEventListener('mousemove', function(e) {
if (dragFlag) {
return;
}
const x = e.clientX;
const y = e.clientY;
const deltaX = x - position[0];
const deltaY = y - position[1];
// parseInt('')空转为 NaN
// drag.style.left初始值为'0px'
const left = parseInt(drag.style.left || 0, 10);
const top = parseInt(drag.style.top || 0, 10);
drag.style.left = left + deltaX + 'px';
drag.style.top = top + deltaY + 'px';
position= [x, y];
})
document.addEventListener('mouseup', function() {
dragFlag = false;
})
filter方法
- 不会对空数组进行检测,会跳过那些空元素
1
2
3
4
5
6
7
8
9
10
11let arr = [0, 3, 5];
arr[10] = 10;
arr.filter((val) => {
return val === undefined;
});
// 初始化
let array = [0, 3, 5, undefined, undefined, null, 123];
array[10] = 10;
array.filter((val) => {
return val === undefined;
});
join()
- javascript 在定义数组的时候允许最后一个元素后跟一个,(分号)
1
2let str = [,,,].join(); // ,,
let str = [,,1,].join('.').length;
普通函数与箭头函数的区别
- this指向的问题,会捕获其所在上下文的this值,作为自己的this值
箭头函数不绑定arguments,取而代之用reset参数解决
1
2
3
4
5
6
7
8
9
10// 箭头函数
let foo = (...args) => {
return args[0];
}
console.log(foo(1));
// 普通函数
fun() {
console.log(argument[0]);
}
console.log(fun(1, 34));箭头函数不能用作构造器,和new一起用就会抛出错误
- 箭头函数没有原型属性
1
2var foo = () => {};
console.log(foo.prototype) // undefined
js常见的自认为正确的问题
1 | var array = []; |
- 解决问题为什么不是0,1,2
- var声明变量,三个箭头函数体中的每个i,都指向相同的绑定,所以它们在循环结束时返回相同的值3
- 解决方法1,把var改为let(let 声明一个具有块级作用域的变量,每个循环迭代创建一个新的绑定)
- 解决方式2,使用闭包
1
2
3
4
5
6
7
8
9
10var array = [];
for(var i = 0; i <3; i++) {
array[i] = (function(x) {
return function() {
return x;
}
})(i);
}
var newArray = array.map(el => el());
console.log(newArray); // [3, 3, 3]
找出字符串中第一次只出现一次的字母
1 | String.prototype.firstAppear = function () { |
获得滚动条的滚动距离
1 | function getScrollOffset() { |
获得视口的尺寸
- To Learn More…
1
2
3
4```
##### 简短函数调用
* 三元操作符来实现多个函数调用
// Longhand
function test1() {
console.log(‘test1’);
};
function test2() {
console.log(‘test2’);
};
var test3 = 1;
if (test3 == 1) {
test1();
} else {
test2();
}
// Shorthand
(test3 === 1? test1:test2)();1
2
3
##### switch 简化
* 将条件保存在键值对象中,并根据条件来调用它们
// Longhand
switch (data) {
case 1:
test1();
break;
case 2:
test2();
break;
case 3:
test();
break;
// And so on…
}
// Shorthand
var data = {
1: test1,
2: test2,
3: test
};
data[something] && datasomething;1
2
##### 延展操作符简化
//longhand
// joining arrays using concat
const data = [1, 2, 3];
const test = [4 ,5 , 6].concat(data);
//shorthand
// joining arrays
const data = [1, 2, 3];
const test = [4 ,5 , 6, …data];
console.log(test); // [ 4, 5, 6, 1, 2, 3]1
* 延展操作符进行克隆
//longhand
// cloning arrays
const test1 = [1, 2, 3];
const test2 = test1.slice()
//shorthand
// cloning arrays
const test1 = [1, 2, 3];
const test2 = […test1];1
2
* 如何将浮点数点左边的数每三位添加一个逗号,如 12000000.11 转化为『12,000,000.11』?
// 方法一
function format(number) {
return number && number.replace(/(?!^)(?=(\d{3})+.)/g, “,”);
}
// 方法二
function format1(number) {
return Intl.NumberFormat().format(number)
}
// 方法三
function format2(number) {
return number.toLocaleString(‘en’)
}1
2
##### 求和,最小值和最大值
const array = [5,4,7,8,9,2];
array.reduce((a, b) => a + b); // 输出: 35
array.reduce((a, b) => a > b ? a : b); // 输出: 9
array.reduce((a, b) => a < b ? a : b); // 输出: 21
2
3
##### 排序字符串,数字或对象等数组
* 内置的方法sort()和reverse()来排序字符串
const stringArr = [“Joe”, “Kapil”, “Steve”, “Musk”]
stringArr.sort();
// 输出 [“Joe”, “Kapil”, “Musk”, “Steve”]
stringArr.reverse();
// 输出 [“Steve”, “Musk”, “Kapil”, “Joe”]1
* 数字数组排序
const array = [40, 100, 1, 5, 25, 10];
array.sort((a,b) => a-b);
// 输出 [1, 5, 10, 25, 40, 100]
array.sort((a,b) => b-a);
// 输出 [100, 40, 25, 10, 5, 1]1
* 对象数组排序
const objectArr = [
{ first_name: ‘Lazslo’, last_name: ‘Jamf’ },
{ first_name: ‘Pig’, last_name: ‘Bodine’ },
{ first_name: ‘Pirate’, last_name: ‘Prentice’ }
];
objectArr.sort((a, b) => a.last_name.localeCompare(b.last_name));
// 输出
(3) [{…}, {…}, {…}]
0: {first_name: “Pig”, last_name: “Bodine”}
1: {first_name: “Lazslo”, last_name: “Jamf”}
2: {first_name: “Pirate”, last_name: “Prentice”}
length: 31
2
##### 从数组中过滤到虚值 (0, undefined, null, false, "", '')
const array = [3, 0, 6, 7, ‘’, false];
array.filter(Boolean);
// 输出 [3, 6, 7]`