# JavaScript

# 数组

# 数组去重

  1. 通过返回原数组filter过滤出首次出现item,从而获得去重后的新数组。

    let arr1 = [1, 2, 4, 4, 2, 5]
    
    function removeRepeat(arr) {
      return arr.filter((item, index, array) => array.indexOf(item) === index)
    }
    
    console.log(removeRepeat(arr1))
    
    1
    2
    3
    4
    5
    6
    7
  2. 通过ES6 Set

    Set中的元素只会出现一次,是唯一的,将原数组存入到Set,然后通过拓展运算符赋值给新数组,得到去重的数组

    let arr2 = [1,2,4,4,2,5]
    let newArr2 = [...new Set(arr2)]
    
    1
    2

console.log(newArr2)



### 扁平化

扁平化就是将多层嵌套的数组转成一层 [1, [2, [3]]]  => [1, 2, 3]

1. 使用数组自带的flat方法

```js
let arr1 = [1, [2, [3]]]

let arr2 = arr1.flat(2)
console.log(arr2) // [ 1, 2, 3 ]
1
2
3
4
5
6
7
8
9
10
11
12
13
  1. 使用while循环,通过原数组的some方法判断item是否为数组,若为数组则继续循环,循环过程中,解构原数组,并通过concat方法合并赋值

    let arr1 = [1, [2, [3]]]
    
    function myFlat(arr){
        while(arr.some(item=>Array.isArray(item))){
            arr = [].concat(...arr)
        }
        return arr
    }
    let arr3 = myFlat(arr1)
    console.log(arr3) // [ 1, 2, 3 ]
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    # 浅拷贝、深拷贝

    • 浅拷贝是指拷贝一层,基本数据拷贝值,引用类型拷贝内存地址。

      • Object.assign({},obj)
      • slice()
      • concat()
      • 拓展运算符
    • 深拷贝是开辟一个新的栈,对应不同的地址。

      深拷贝可以使用JSON.stringify()实现

      注意:使用JSON.stringify()弊端:

      // 弊端 会忽略undefined、symbol和函数
      const obj3 = {
          name: 'A',
          name1: undefined,
          name3: function() {},
          name4:  Symbol('A')
      }
      const obj4 = JSON.parse(JSON.stringify(obj3));
      console.log(obj4); // {name: "A"}
      
      1
      2
      3
      4
      5
      6
      7
      8
      9

      手写深拷贝代码:

      
      
      1

# apply

# 操作动画 Web Animation API

onst keyframes = [
  { transform: 'translateX(0)' ,offset: 0.1},
  { transform: 'translateX(-60%)' ,offset: 0.9},
  { transform: 'translateX(0)' ,offset: 1},
]
const options = {
  duration: 8000,
  iterations: Infinity
}

const element = document.querySelector('.animate');
const webAnimation = element.animate(keyframes, options);
1
2
3
4
5
6
7
8
9
10
11
12

# findIndex() 查找数组中对象索引

用于在数组中查找对象对象的索引,事例如下:

const ages = [3, 10, 17, 23, 52, 20];
let index = ages.findIndex( age => age > 18);
console.log(index);
1
2
3

# 数组方法

var str="How are you doing today?";
var n=str.split(" "); 
// How,are,you,doing,today? 

string.split(separator,limit)
separator:可选。字符串或正则表达式,从该参数指定的地方分割 string Object。
limit:可选。该参数可指定返回的数组的最大长度。如果设置了该参数,返回的子串不会多于这个参数指定的数组。如果没有设置该参数,整个字符串都会被分割,不考虑它的长度。

返回:Array
1
2
3
4
5
6
7
8
9

slice() 提取字符串的片断

splice() 用于添加或删除数组中的元素

array.splice(index,howmany,item1,.....,itemX)
1

unshift()向数组的开头添加一个或更多元素,并返回新的长度

var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.unshift("Lemon","Pineapple"); 
// Lemon,Pineapple,Banana,Orange,Apple,Mango
1
2
3

# 数组去重

方法一:
采用对象访问属性的方法,判断属性值是否存在,如果不存在就添加。
方法二:
采用数组中的reduce方法,遍历数组,也是通过对象访问属性的方法
var arr = [{
   key: '01',
   value: '乐乐'
  }, {
   key: '02',
   value: '博博'
  }, {
   key: '03',
   value: '淘淘'
  },{
   key: '04',
   value: '哈哈'
  },{
   key: '01',
   value: '乐乐'
  }];
  // 方法1:利用对象访问属性的方法,判断对象中是否存在key
  var result = [];
  var obj = {};
  for(var i =0; i<arr.length; i++){
   if(!obj[arr[i].key]){
     result.push(arr[i]);
     obj[arr[i].key] = true;
   }
  }
  console.log(result); // [{key: "01", value: "乐乐"},{key: "02", value: "博博"},{key: "03", value: "淘淘"},{key: "04", value: "哈哈"}]


  // 方法2:利用reduce方法遍历数组,reduce第一个参数是遍历需要执行的函数,第二个参数是item的初始值
  var obj = {};
  arr = arr.reduce(function(item, next) {
   obj[next.key] ? '' : obj[next.key] = true && item.push(next);
   return item;
  }, []);
  console.log(arr); // [{key: "01", value: "乐乐"},{key: "02", value: "博博"},{key: "03", value: "淘淘"},{key: "04", value: "哈哈"}]

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

# encodeURIComponent()函数在url传参中的作用和使用方法

来源:https://cloud.tencent.com/developer/article/1736258

# 为什么使用 encodeURIComponent()

在使用 URL 传参的时候,如果参数中有空格等特殊字符,浏览器可能只会读取到空格面前的内容,导部分致数据丢失。

可以使用 encodeURIComponent() 方法,将这些特殊字符进行转义,这样就可以正常读取了。

# 定义和用法:

encodeURIComponent() 函数可把字符串作为 URI 组件进行编码。

# 语法:

encodeURIComponent(URIstring)
1

# 参数:

URIstring必需。一个字符串,含有 URI 组件或其他要编码的文本。

# 返回值:

URIstring 的副本,其中的某些字符将被十六进制的转义序列进行替换。

# 注意:

1、该方法不会对 ASCII 字母和数字进行编码,也不会对这些 ASCII 标点符号进行编码: - _ . ! ~ * ' ( ) 。

2、其他字符(比如 :;/?😡&=+$,# 这些用于分隔 URI 组件的标点符号),都是由一个或多个十六进制的转义序列替换的。

3、请注意 encodeURIComponent() 函数 与 encodeURI() 函数的区别之处,前者假定它的参数是 URI 的一部分(比如协议、主机名、路径或查询字符串)。因此 encodeURIComponent() 函数将转义用于分隔 URI 各个部分的标点符号。

# 应用:

如果我们要将一个对象通过 URL 进行传输,可以将对象转成字符串,再用 encodeURIComponent() 函数进行转义:

encodeURIComponent(JSON.stringify(cardOBJ))
1

然后将接收的参数转换成对象:

JSON.parse(decodeURIComponent(params.cardOBJ))
1

这里的:

decodeURIComponent() 用于对 encodeURIComponent() 进行反转义。

JSON.stringify() 方法用于将 JavaScript 值转换为 JSON 字符串。

JSON.parse() 方法用于将一个 JSON 字符串转换为对象。

# 正则

/**
 * Created by jiachenpan on 16/11/18.
 */

const validUsername = (str) => {
  const valid_map = ['admin', 'editor']
  return valid_map.indexOf(str.trim()) >= 0
}

function valid(reg) {
  return function (str) {
    reg.lastIndex = 0
    return reg.test(str)
  }
}

/* 合法uri*/
const validateURL = valid(
  /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/
)

/* 小写字母*/
const validateLowerCase = valid(/^[a-z]+$/)

/* 大写字母*/
const validateUpperCase = valid(/^[A-Z]+$/)

/* 大小写字母*/
const validateAlphabets = valid(/^[A-Za-z]+$/)

// 校验邮箱
const validateEmail = valid(
  /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
)

// 校验手机号码
const validateMobilePhone = valid(
  /^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/g
)

// 校验电话号码
const validateTelephone = valid(/\d{3}-\d{8}|\d{4}-\d{7}/g)

// 校验联系方式(手机号码或电话号码)
const validateContactsTel = (str) => {
  return validateMobilePhone(str) || validateTelephone(str)
}

// 校验营业执照编号/统一社会信用代码
const validateUscId = valid(/^([0-9A-HJ-NPQRTUWXY]{2}\d{6}[0-9A-HJ-NPQRTUWXY]{10}|[1-9]\d{14})$/)

// 校验内地身份证
const validIdCard = valid(/(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/)

// 校验香港身份证
const validHongKongCard = valid(/^[HMhm]{1}([0-9]{10}|[0-9]{8})$/)

// 校验身份证
const validateIdCard = (str) => {
  return validIdCard(str) || validHongKongCard(str)
}

// 新能源车牌校验
const EnergyVehicleReg =
  /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}(([0-9]{5}[DF]$)|([DF][A-HJ-NP-Z0-9][0-9]{4}$))/
const validateNewEnergyVehicle = valid(EnergyVehicleReg)

// 普通车牌号校验
const vehicleReg =
  /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳]{1}$/
const validateNormalVehicle = valid(vehicleReg)

// 校验车牌号
const validateVehicle = (vehicleNumber) => {
  return validateNormalVehicle(vehicleNumber) || validateNewEnergyVehicle(vehicleNumber)
}

export {
  validUsername,
  validateURL,
  validateLowerCase,
  validateUpperCase,
  validateAlphabets,
  validateEmail,
  validateMobilePhone,
  validateTelephone,
  validateContactsTel,
  validateUscId,
  validIdCard,
  validHongKongCard,
  validateIdCard,
  validateNormalVehicle,
  validateNewEnergyVehicle,
  validateVehicle
}
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
上次更新: 7 minutes