反复刷这些javascript面试手写题,我感觉我真的变强了
Posted 阿锋不知道丶
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了反复刷这些javascript面试手写题,我感觉我真的变强了相关的知识,希望对你有一定的参考价值。
文章目录
用正则能实现的手写题
前段时间刚好复习了正则,所以把正则的写前面
实现千分位分隔符
题目描述:实现将一个数从各位数开始,每距离一个千分位添加一个分割符 ‘ ,’
如输入: 12345678.32423432
输出:12,345,678.32423432
这道题在最近一两个月的面试中遇到两次,可以分别有字符串和数组的一些方法结合解决,也可以用正则解决,我觉得正则可能更难以理解
第一种方法:
const num = 12345678.32423432
function getForm(num) {
let arr = num.toString().split('.')
// 取出整数部分
let arr0 = arr[0].split('')
// console.log(arr0);
let stack = []
let i = 0
while (arr0.length > 0) {
// 没3位添加一个分割符
if (i % 3 == 0 && i !== 0) {
stack.push(',')
}
stack.push(arr0.pop())
i++
}
let res = stack.reverse()
console.log(res);
// 考虑是否存在小数部分
if (arr[1]) {
return res.join('') + '.' + arr[1]
} else {
return res.join('')
}
}
console.log(getForm(num));
第二种方法用正则解决:
function regForm(num) {
// console.log(num.toString());
return num.toString().replace(/\\d+/, (p) => {
return p.replace(/\\d(?=(\\d{3})+$)+/g, (p1, p2) => {
return p1 + ','
})
})
}
实现一个trim()
实现string原型上的trim()方法:
解决方法有很多,我常用的是下面这两个
String.prototype.my_trim = function () {
return this.replace(/^\\s+/, '').replace(/\\s+$/, ' ')
}
String.prototype.trim = function() {
return this.replace(/^\\s+|\\s+$/g, '');
}
取出连续重复的字符
取出 :'sadddddddddddddsssssssssssssdddddddasddd’重复的字符
最终为 [“ddddddddddddd”, “sssssssssssss”, “ddddddd”, “ddd”]
面试腾讯暑期实习生遇到此题,我当时真的菜没做出来,回过头来发现真简单
let a = 'sadddddddddddddsssssssssssssdddddddasddd'
console.log(a.match(/([a-z])\\1+/ig));
解析url参数为对象形式
const url = 'http://www.baidu.com/we/index.html?id=098&aaa=123&ccc=456'
function parseParam(url) {
let arr = url.split('?')[1].split('&')
console.log(arr);
let obj = {}
arr.forEach(item => {
console.log(item.split('='));
let [key, value] = item.split('=')
if (/^\\d+$/.test(value)) {
value = parseInt(value)
}
obj[key] = value
})
return obj
}
console.log(parseParam(url));
关于闭包的手写题
自我感觉这部分的手写题能够全部理解的话,对于闭包的理解会更加深刻
利用高阶函数实现函数缓存
高阶函数应该就是输入参数是函数,返回也是一个函数
var add = function (a) {
return a + 1
}
function memo(fn) {
const cache = {}
return function (...ret) {
let key = JSON.stringify(ret)
return cache[key] || (cache[key] = fn.apply(fn, [...ret]))
}
}
const adder = memo(add)
console.log(adder);
console.log(adder(1));
console.log(adder(1));
console.log(adder(3));
console.log(adder(3));
手写call,apply,bind
这几个函数只有把手写学会才会理解的更深刻
柯里化-实现实现一个add(1)(2)(3)
具体要求就是能使本来函数add(1,2,3)变成add(1)(2)(3)
具体思路就是将参数用递归的方式一个一个的传入目标函数
function curry(fn, args) {
var ofArgs = args || []
var len = fn.length
var self = this
//
return function (...ret) {
// ret是后面传入的函数
var currentArg = [...ofArgs, ...ret]
console.log(currentArg);
// 如果当前参数数组的长度小于fn的要求长度 那么继续递归
if (len > currentArg.length) {
return curry.call(self, fn, currentArg)
}
return fn.apply(self, currentArg)
}
}
const add = function (a, b, c) {
return a + b + c
}
const newFn = curry(add)
// newFn(1)(2)(3)
console.log(newFn(1)(2)(3));
防抖和节流
关于对象
手写深拷贝
拷贝一个地址不同其他完全相同的对象
function deepClone(obj) {
if (typeof obj !== 'object') {
return obj
}
let res
// 数组和对象的限定
if (Array.isArray(obj)) {
res = []
} else {
res = {}
}
//一层层递归赋值
for (let key in obj) {
console.log(key);
if (obj.hasOwnProperty(key)) {
res[key] = obj[key]
}
}
return res
}
let book = {
name: "局外人",
types: {
t1: "中文版",
t2: "英文版",
a: {
c: 2
}
}
}
5
let book_clone = deepClone(book)
console.log(book_clone === book);
console.log(book_clone);
手写深度比较
深度比较两个对象的值是否完全相同
function isEqual(obj1, obj2) {
// 判断两个是不是对象
if (typeof obj1 !== 'object' && typeof obj2 !== 'object'
&& obj1 !== null && obj2 !== null) {
return obj1 === obj2
}
if (obj1 === obj2) {
return true
}
// 先取出obj1和obj2的keys,比较个数
let leng1 = Object.keys(obj1).length
let leng2 = Object.keys(obj2).length
// console.log(leng1);
if (leng1 !== leng2) {
return false
}
// 以obj1为基准和obj2递归比较
for (let key in obj1) {
const res = isEqual(obj1[key], obj2[key])
if (!res) {
return false
}
}
return true
}
const obj1 = {
a: 2,
b: 'a',
c: {
e: 'f',
f: 's'
}
}
const obj2 = {
a: 2,
b: 'a',
c: {
e: 'f',
f: 's',
// a: 41
}
}
console.log(isEqual(obj1, obj2));
关于数组
数组去重
最简单的去重:用set
var arr = [1, 1, 'true', 'true', true, true, 15, 15, false, false, undefined, undefined, null, null, NaN, NaN, 'NaN', 0, 0, 'a', 'a', {}, {}];
console.log(unique(arr));
// 注意Set是能够去掉NaN的重复的
// [...new Set(arr)]
function unique(arr) {
return Array.from(new Set(arr))
}
使用indexOf无法去除 NaN的重复 indexOf(NaN)永远等于-1
var arr = [1, 1, 'true', 'true', true, true, 15, 15, false, false, undefined, undefined, null, null, NaN, NaN, 'NaN', 0, 0, 'a', 'a', {}, {}];
console.log(unique(arr));
function unique(arr) {
if (!Array.isArray(arr)) {
{
console.log('is nor a array');
}
}
const res = []
arr.forEach(element => {
if (res.indexOf(element) === -1) {
res.push(element)
}
});
return res
}
includes也是能够去掉NaN的重复的
var arr = [1, 1, 'true', 'true', true, true, 15, 15, false, false, undefined, undefined, null, null, NaN, NaN, 'NaN', 0, 0, 'a', 'a', {}, {}];
console.log(unique(arr));
function unique(arr) {
if (!Array.isArray(arr)) {
throw new TypeError('is not array')
}
const new_arr = []
arr.forEach(e => {
if (!new_arr.includes(e)) {
new_arr.push(e)
}
})
return new_arr
}
splice使用此函数特别需要注意的一点:会改变数组,改变数组的长度
var arr = [1, 1, 'true', 'true', true, true, 15, 15, false, false, undefined, undefined, null, null, NaN, NaN, 'NaN', 0, 0, 'a', 'a', {}, {}];
console.log(unique(arr));
function unique(arr) {
let len = arr.length
for (let i = 0; i < len; i++) {
for (let j = i + 1; j < len; j++) {
if (arr[i] == arr[j]) {
// console.log(arr);
arr.splice(j, 1)
// console.log(arr);
j--;
}
}
}
return arr
}
用filter+hasOwnProperty两个空对象也能去重
var arr = [1, 1, 'true', 'true', true, true, 15, 15, false, false, undefined, undefined, null, null, NaN, NaN, 'NaN', 0, 0, 'a', 'a', {}, {}];
console.log(unique(arr));
function unique(arr) {
var obj = {};
return arr.filter(function (item, index, arr) {
console.log(item);
console.log(typeof item + item);
// console.log(obj[typeof item + item]);
// 判断obj对象是否有这个属性,如果有(说明数组元素重复)直接返回false过滤掉数组中的重复元素
// 如果没有,为obj对象添加上这个属性
return obj.hasOwnProperty(typeof item + item) ? false : (obj[typeof item + item] = true)
})
}
数组乱序
主要用到的api是Match.random和set
function disorder(arr) {
let len = arr.length
let res = []
let remember = new Set()
// console.log(remember.size);
while (remember.size < len) {
let randomNum = Math.floor(len * Math.random())
if (!remember.has(randomNum)) {
res.push(arr[randomNum])
remember.add(randomNum)
}
}
return res
}
console.log(disorder([1, 2, 3, 4, 5, 6, 7, 8, 9]));
手写数组filter方法
先具体了解一下filter -MDN
反复刷这些javascript手写题,我又变强了