记录一些JS考点

100个请求,最大并发10 ,最后得到一个数组,是所有请求的返回结果,顺序和请求地址数组一致。

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
const urls = []

for(var i=0 ; i<10; i++) {
urls.push(`https://newcar.xcar.com.cn/auto/index.php?r=Ajax/GetUsedCars&province_id=${i}`)
}

conCurRequest(urls,3).then(res=>{
console.log(res)
})

function conCurRequest(urls,maxNum) {
return new Promise(resolve=>{
if(urls.length === 0) {
resolve([])
return
}
const results = []
// 每次取出这个索引指向的URL地址
let index = 0
// 请求完成的数量
let count = 0;
async function request() {
//如果发送的地址超过了URL数组的长度
if(urls.length === index) {
return
}


//保存之前的url数组的index,按顺序保存入返回的数组用
const i = index;
let url = urls[index]
console.log(url)
index++;

try{
const reps = await fetch(url)
results[i] = reps
}catch(e) {
//不管成功或者失败,都把结果按顺序放入数组中
results[i] = err
}
finally{
//无论成功失败都继续发送下一次请求
request()
count++;
//发送所有url完成 reslove结果
if(urls.length === count) {
console.log('所有请求都已完成')
resolve(results)
}
}

}
const times = Math.min(maxNum,urls.length);
for(var i=0; i< times; i++) {
request()
}

})
}


js 深拷貝

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
function deepClone(obj={}){
if(typeof obj !='object' || obj != null){
// obj如果不是对象或者数组,是null,直接返回
return obj
}

// 初始化返回结果
let result
if(obj instanceof Array){
result = []
}else{
result = {}
}

for(let key in obj){
// 保证 key 不是原型的属性
if(obj.hasOwnProperty(key)){
// 递归调用!!!!
result[key] = deepClone(obj[key])
}
}
// 返回结果
return result
}

let obj1 = {
age:20,
name:'xxx',
address:{
city:'beijing'
},
arr:['a','b','c']
}

let obj2 = deepClone(obj1)

obj2.age = 21;
console.log(obj1.age) // 20;




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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
export const $ = function() {
var copyIsArray,
toString = Object.prototype.toString,
hasOwn = Object.prototype.hasOwnProperty,

class2type = {
'[object Boolean]': 'boolean',
'[object Number]': 'number',
'[object String]': 'string',
'[object Function]': 'function',
'[object Array]': 'array',
'[object Date]': 'date',
'[object RegExp]': 'regExp',
'[object Object]': 'object'
},

type = function(obj) {
return obj == null ? String(obj) : class2type[toString.call(obj)] || "object";
},

isWindow = function(obj) {
return obj && typeof obj === "object" && "setInterval" in obj;
},

isArray = Array.isArray || function(obj) {
return type(obj) === "array";
},

isPlainObject = function(obj) {
if (!obj || type(obj) !== "object" || obj.nodeType || isWindow(obj)) {
return false;
}

if (obj.constructor && !hasOwn.call(obj, "constructor") &&
!hasOwn.call(obj.constructor.prototype, "isPrototypeOf")) {
return false;
}

var key;
for (key in obj) {}

return key === undefined || hasOwn.call(obj, key);
},

extend = function(deep, target, options) {
for (var name in options) {
var src = target[name];
var copy = options[name];

if (target === copy) {
continue;
}

if (deep && copy &&
(isPlainObject(copy) || (copyIsArray = isArray(copy)))) {
if (copyIsArray) {
copyIsArray = false;
var clone = src && isArray(src) ? src : [];

} else {
var clone = src && isPlainObject(src) ? src : {};
}

target[name] = extend(deep, clone, copy);
} else if (copy !== undefined) {
target[name] = copy;
}
}

return target;
};

return { extend: extend };
}();

比较两个元素(可以是数组,字符串,对象)是否相等

https://juejin.cn/post/6989513100856672293

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
// 实现如下效果
const obj1 = {a: 10, b: {x: 100, y:200 }}
const obj2 = {a: 10, b: {x: 100, y:200 }}
isEqual(obj1, obj2) === true

function isObject(obj){
return typeof obj === 'object' && obj != null
}
function isEqual(obj1,obj2){
//
if(!isObject(obj1) || !isObject(obj2)){
return obj === obj2
}
if(obj1===obj2){
return true
}
// 两个都是对象或数组,而且不相等
// 1.先取出 obj1 和 obj2 的keys 比较个数
const obj1Keys = Object.keys(obj1)
const obj2Keys = Object.keys(obj2)
if(obj1Keys.length != obj2Keys.length){
return false
}
// 2.以obj1为基准,和obj2 依次递归比较
for(let key in obj1){
// 比较当前的key的val
const res = isEqual(obj1[key],obj2[key])
if(!res){
return false
}
}
// 3.全相等
return true
}


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
const obj = {
name : "1",
other:{
name:'imooc'
}
}

const obj1 = {
name : "1",
other:{
name:'imooc'
}
}

function compare(obj1,obj2){
//如果只比较数组,字符串,数字 直接返回真
if(obj1 == obj2){
return true
}
//对象的key的数量不一样返回假
if(Object.keys(obj1).length!== Object.keys(obj2).length){
return false
}
//循环 对象 如果key的值还是一个对象递归判断
for(let k in obj1){
if(Object.prototype.toString.call(obj1[k]) == "[object Object]"){
return compare(obj1[k],obj2[k])
}
else if(obj1[k]!==obj2[k]){
return false
}
}

return true
}


console.log(compare(obj,obj1))


取最大值最小值之间随机的一个数

1
2
3
4
5
6
7
8
function Random(min,max)
{
var num = max - min + 1; //最大值 - 最小值 +1 取得最小和最大之间可能有几个值
return Math.floor(Math.random() * num + min) //高级程序设计中提到的公式,P136
}

console.log(Random(0,5))
{% endhighlight %}

利用 apply 取数组中最大或最小值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//因为不支持Math.max([1,2,3])这种写法,就是不能直接传入一个数组,
//但是它支持Math.max(param1,param2...)
//所以可以变相通过 apply(apply和call的区别就是传入参数不同)
//调用的时候第一个参数给了null,这是因为没有对象去调用这个方法,我只需要用这个方法帮我运算,得到返回的结果就行,所以直接传递了一个null过去。
var arr = [1,2,3,5,6];
function getMax(arr){
return Math.max.apply(null,arr)
}
function getMin(arr){
return Math.min.apply(null,arr)
}
alert(getMax(arr));
alert(getMin(arr));

//ES6 写法
Math.max(...[1,2,3]) //3

点击按钮,有三种状态 一直输出 1,2,3…1,2,3…1,2,3

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<body>
<button onclick="fn1()">click</button>
<div id="txt"></div>
<script type="text/javascript">
var a = 0;

var txt = document.getElementById('txt')
function fn1(){
a = a + 1;
console.log(a%3)
}

</script>
</body>

统计出现次数最多的字符

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
String.prototype.max_num = function(){
var obj = {}
var res;
var max_num = 0;
var max_key;
for(var i=0; i<this.length; i++)
{
res = this[i];
if(!obj[res])
{
obj[res] = 1
}
else
{
obj[res]++;
}
}
for(var key in obj)
{
if(max_num < obj[key])
{
max_num = obj[key];
max_key = key;
}

}

return max_key

}

alert(str.max_num())

手写 flatern 考虑多层级(数组拍平)

1
2
3
4
5
6
7
8
9
10
11
12
13
function flat(arr){
//验证arr中还有没有深层数组
const isDeep = arr.some(item=>item.instanceof Array)
if(!isDeep) return arr
const res = Array.prototype.concat.apply([],arr)
return flat(res)
}
const res = flat([1,2,[3,4]])
console.log(res) // [1,2,3,4]

Array.prototype.flat([depth]) //默认为1,Infinity 无限层


数组去重

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Array.prototype.unique1 = function()
{
var n = [];
for(var i=0; i< this.length;i++)
{
if(n.indexOf(this[i]) == -1)
{
n.push(this[i])
}
}
return n;
}

var array1 = [1,2,2,4,4,1,5,6]
var s = array1.unique1();
console.info(s)

全选全不选反选

1
2
3
4
5
6
7
8
9
10
11
12
13
<input type="button" value="全选/全不选" id="button1" />
<input type="button" value="反选" id="button2" />
<div id="div1">
<input type="checkbox" />
<input type="checkbox" />
<input type="checkbox" />
<input type="checkbox" />
<input type="checkbox" />
<input type="checkbox" />
<input type="checkbox" />
<input type="checkbox" />

</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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
window.onload = function()
{
var flag = true; //全选,全不选的按钮的标志
var btn1 = document.getElementById("button1");
var btn2 = document.getElementById("button2");
var oDiv = document.getElementById("div1");
var aInput = oDiv.getElementsByTagName("input");
//初始让所有复选框都不选中,为了兼容IE FF
for(var i=0 ;i<aInput.length;i++)
{
aInput[i].checked = false;
}

btn1.onclick = function()
{
if(flag)
{
for(var i=0 ;i<aInput.length;i++)
{
aInput[i].checked = true;
}
flag = false;
}
else
{
for(var i=0 ;i<aInput.length;i++)
{
aInput[i].checked = false;
}
flag = true;
}


}

btn2.onclick = function()
{
for(var i=0 ;i<aInput.length;i++)
{
if(aInput[i].checked == true)
{
aInput[i].checked = false
}
else
aInput[i].checked = true;
}
}
}