Silencer-1984 / Summary-of-front-end-work

总结包括一切关于前端学习的东西,面试、学英语、开发规范
0 stars 0 forks source link

常见手写题 #25

Open Silencer-1984 opened 3 years ago

Silencer-1984 commented 3 years ago

url拆解

/**
 * --- 题目描述 ---
 *
 * 实现一个 parseParem 函数,将 url 转化为指定结果
 *
 * --- 测试用例 ---
 *
 * 输入:url = 'http://www.domain.com/?user=anonymous&id=123&id=456&city=%E5%8C%97%E4%BA%AC&enabled'
 * 输出:
{
 user:'anonymous',
 id:[123,456],// 重复出现的 key 要组装成数组,能被转成数字的就转成数字类型
 city:'北京',// 中文需解码
 enabled: true // 未指定值的 key 与约定为 true
}
 */
const parseParem = (url) => {
    const arr = url.split('?')[1].split('&');
    const res = {};
    arr.forEach((e) => {
        let key = e.split('=')[0], value = e.split('=')[1];
        if (value === undefined) {
            res[key] = true; // 按照题目规则写出空key的值
        } else {
            if (key in res) {
                 // 数组索引转为数字类型
                Array.isArray(res[key]) ? res[key].push(value) : res[key] = [res[key]].concat(value); 
            } else {
                res[key] = decodeURI(value) // 转移中文
            }
        }
    })
    return res;
}
// 简单版
function getQueryObj(url) {
    // TODO
    let arr = url.split('?')[1].split('#')[0].split('&');
    const res = {};
    arr.forEach(e => {
        const [key, value] = e.split('=');
        if (!value) {
            res[key] = '';
        } else {
            res[key] = value;
        }
    })
    return res;
}

字符串转换为对象

/**
 * --- 题目描述 ---
 *
 * 实现一个方法,把 HTTP 文本形式(字符串)的 header 转换成 JS 对象。
 * 
 * --- 测试用例 ---
 * 
 * 输入:
 * `Accept-Ranges: bytes 
 * Cache-Control: max-age=6000, public
 * Connection: keep-alive
 * Content-Type: application/javascript`
 * 输出:
 * {
 *   "Accept-Ranges": "bytes",
 *   "Cache-Control": "max-age=6000, public",
 *   Connection: "keep-alive",
 *   "Content-Type": "application/javascript"
 * }
 *
 * --- 解题思路 ---
 *
 * 1. 首先将每行数据作为数组的一个元素
 * 2. 将每个元素使用冒号分割,前面为 `key`,后面为 `value`。
 */

const solution = (s) => {
    let res = {};
    let arr = s.split("\n");
    arr.forEach((e) => {
        let tmp = e.split(": ");
        res[tmp[0]] = tmp[1];
    })
    return res;
}

数组扁平化

数组扁平化就是指把多层的数组转化成只有一层的数组

[1, [2, [3,4]]] => [1,2,3,4]

递归解法

var arr = [1, [2, [3, 4]]];

function flatten(arr) {
    var result = [];
    for (var i = 0, len = arr.length; i < len; i++) {
        if (Array.isArray(arr[i])) {
            result = result.concat(flatten(arr[i]))
        }
        else {
            result.push(arr[i])
        }
    }
    return result;
}

es6解法

var arr = [1, [2, [3, 4]]];

function flatten(arr) {

    while (arr.some(item => Array.isArray(item))) {
        arr = [].concat(...arr);
    }
    return arr;
}

Array.flat解法

**flat()** 方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回,参数默认为1

const arr1 = [0, 1, 2, [3, 4]];

console.log(arr1.flat());
// expected output: [0, 1, 2, 3, 4]

const arr2 = [0, 1, 2, [[[3, 4]]]];

console.log(arr2.flat(2));
// expected output: [0, 1, 2, [3, 4]]
const arr1 = [0, 1, 2, [[[3, 4]]]];
arr1.flat(3)

模拟 lodash 中的 _.get() 函数

/**
 * --- 题目描述 ---
 *
 * 补充函数的 TODO 部分,模拟 lodash 中的 _.get() 函数。
 *
 * --- 测试用例 ---
 *
 * 输入:
 * const obj = { selector: { to: { toutiao: "FE Coder"} }, target: [1, 2, { name: 'byted'}]};
 * get(obj, 'selector.to.toutiao', 'target[0]', 'target[2].name')
 * 输出:
 * ['FE coder', 1, 'byted']
 */

function get(object, ...path) {
    return path.map((item) => {
        item.replace(/\[/g, ".")
            .replace(/\]/g, "")
            .split('.')
            .map(path => object = object && object[path]);
        return object;
    })
}

实现一个Promise.all()

function promiseAll(promises) {
  return new Promise(function(resolve, reject) {
    if (!isArray(promises)) {
      return reject(new TypeError('arguments must be an array'));
    }
    var resolvedCounter = 0;
    var promiseNum = promises.length;
    var resolvedValues = new Array(promiseNum);
    for (var i = 0; i < promiseNum; i++) {
        (function(i) {
            Promise.resolve(promises[i]).then(function(value) {
            resolvedCounter++
            resolvedValues[i] = value
            if (resolvedCounter == promiseNum) {
                return resolve(resolvedValues)
            }
            }, function(reason) {
            return reject(reason)
            })
        })(i)
    }
  })
}

防抖

// debounce
function debounce(fn, delay=500) {
    // timer 写在闭包中,因此防抖也是闭包的一个应用
    let timer = null;

    return function() {
        if (timer) {
            clearTimeout(timer)
        }
        timer = setTimeout(() => {
            fn.apply(this, arguments);
            timer = null;
        }, delay)
    }
}

// 验证
input1.addEventListener('keyup', debounce(() => {
    console.log(input1.value);
}), 600)

收写节流

// 节流
function throttle(fn, delay = 100) {
    let timer = null

    return function() {
        if (timer) {
            return
        }
        timer = setTimeout(() => {
            fn.apply(this, arguments)
            timer = null
        }, delay)
    }
}

div1.addEventListener(('drag', throttle(function (e) {
    console.log(e.offsetX, e.offsetY)
})))
Silencer-1984 commented 3 years ago

简单手写ajax

get请求

const xhr = new XMLHttpRequest()
xhr.open('GET', '/api', true)
xhr.onreadystatechange = function(){
    if(xhr.readyState === 4){
        if(xhr.status === 200){
            console.log(xhr.responseText)
        }
    }
} 
xhr.send(null)

post请求

const xhr = new XMLHttpRequest()
xhr.open('POST', '/api', true)
xhr.onreadystatechange = function(){
    if(xhr.readyState === 4){
        if(xhr.status === 200){
            console.log(xhr.responseText)
        }
    }
} 
const postData = {}
xhr.send(JSON.stringify(postData))