面试题积累

Javascript

正则

  • 匹配整数
1
2
3
4
5
6
7
var str = '102'
// 1. ^(-|\+) 以 - 或者 + 开头
// 2. ? 表示出现或者不出现
// 3. [1-9] 取值范围,也是首字符的取值范围
// 4. \d*$ :* 等价于{0,},表示出现任意次,有可能不出现。
var reg = /^(-|\+)?[1-9]\d*$/
reg.test(str)
  • 用正则把[1,2,3,4]转换成 '1', '2', '3', '4'
1
[1, 2, 3, 4].join().replace(/([^,])/g, "'$1'") // 逗号结尾的字符分组,加引号
  • dgfhfgh254bhku289fgdhdy675gfh 输出 [254,289,675]
1
2
3
4
5
var str = 'dgfhfgh254bhku289fgdhdy675gfh'
str.replace(/\d{3}/g, $1 => arr.push(+$1)) // 匹配出现3个数字的字符,+$1 转化为整数

// question 假如要匹配连续出现的数字呢? ↓↓↓
str.replace(/\d+/g, $1 => arr.push(+$1)) // + 匹配至少出现一次的数字
  • 匹配数字范围
1
2
// 限制 1000-2000,整数
const reg = /^-?(?:[0-9]{1,3}|1000)$/
  • 字符串去重,把 aaacabbbccc 变成 abc
1
2
3
4
5
6
7
var str = 'aaacabbbbcccc'
var reg = /(.).*\1/g
str.replace(reg, '$1')

// \1 表示的引用之前的那个分组 不管它匹配到什么(比如-),\1都匹配那个同样的具体某个字符。

var reg = /(\w)\1+/g // 匹配连续出现的字符
  • 匹配一年中的 12 个月
1
2
3
4
5
6
var str = '12'
var reg = /^(0?[1-9]|1[0-2])$/g
console.log(reg.test(str))

// 首位 0 时,第二位 1-9
// 首位 1 时,第二位 0-2

理论补充

  • 非捕获分组 ?:

    (?:)会作为匹配校验,并出现在匹配结果字符里面,但不作为子匹配返回。

1
2
3
4
5
var reg1 = /1(2)/
var reg2 = /1(?:2)/

'12'.match(reg1) // "12", "2"...
'12'.match(reg2) // "12", ...

作用域, eventLoop,异步…

  1. 经典题
1
2
3
4
5
6
7
8
9
10
11
12
13
for (var i = 0; i < 5; i++) {
setTimeout(() => {
console.log(i)
}, i * 1000)
} // 结果:每一秒输出一个5

// settimeout 是异步, 每一秒在任务队列中添加任务。等主线执行完成后再执行任务队列里的任务

var => let // 解决变量作用域

// 为for循环头部的let不仅将i绑定到for循环快中,事实上它将其重新绑定到循环体的每一次迭代中,确保上一次迭代结束的值重新被赋值。
// setTimeout里面的function()属于一个新的域,通过 var 定义的变量是无法传入到这个函数执行域中的,通过使用 let 来声明块变量,
// 这时候变量就能作用于这个块,所以 function就能使用 i 这个变量了
  1. this 的考察
1
2
3
4
5
6
7
8
9
10
11
12
function f() {
y = function() {
x = 2
}
return function() {
var x = 3
y()
console.log(this.x)
}.apply(this, arguments)
}

f() // 2
  1. 变量提升
1
2
3
4
5
6
7
8
9
10
11
12
13
var a = 1
function outer() {
var a = 2
function inner() {
a++
console.log(a)
var a = 3
console.log(a)
}
inner()
}

outer() // NaN 3

其他

  • 遍历 html 中所有 dom 节点,并计算 dom 节点数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var doms = []
function getChildren(parent) {
if (parent.children.length > 0) {
for (let i = 0; i < parent.children.length; i++) {
getChildren(parent.children[i])
}
}
if (parent.nodeType === 1) {
// parent.nodeType === 1:节点是一个元素节点
doms.push(parent)
}
}

getChildren(document)

console.log(doms)
  • 随机数
1
2
3
var random = (m, n) => m + Math.floor(Math.random() * (n - m))

random(1, 4) // 产生 1-4 之间的随机数
  • 实现数组乱序
1
2
3
4
5
6
7
8
9
10
11
12
function shuffle(array) {
let len = array.length
let temp
while (len) {
const i = Math.floor(Math.random() * len--)
temp = array[len]
array[len] = array[i]
array[i] = temp
}
return array
}
shuffle([1, 3, 4, 5, 7])