一名【合格】前端工程师的自检清单(JavaScript编码能力篇)

it2022-05-05  122

#JavaScript编码能力

 

##1.多种方式实现数组去重、扁平化、对比优缺点

参考资料:

https://blog.csdn.net/xiaobing_hope/article/details/79458288

https://blog.csdn.net/ganyingxie123456/article/details/77947704

 

###简单数组去重

 

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

// 去重后

arr = [1, 43, 4, 3, 2]

 

// 传统方法,for循环实现

 

function dedupe(arr) {

var rets = [];

for (var i = 0; i < arr.length; i ++) {

if (!rets.includes(arr[i])) {

rets.push(arr[i]);

}

}

return rets;

}

 

// 方法二: forEach方法实现

function dedupe(arr) {

var rets = [];

arr && arr.forEach(function(item){

if (!rets.includes(item)){

rets.push(item);

}

});

return rets;

}

 

// ES6方法实现

 

// es6提供的新的数据结构Set,类似数组,但是成员的值都是唯一的,没有重复的值。

function dedupe(arr) {

var newSet = new Set(arr); // arr变成了set的数据结构,并去除了其中重复的元素

return Array.from(newSet); // Array.from方法将set数据结构转为数组数据结构

}

 

###复杂数据结构的数组去重

 

// [1,2,{a:1},3,2,{a:1},[1,2],[1,2]]

// 数组中的元素包含对象和数组

 

function unique(arr) {

const hash = {};

const res = [];

for (let i = 0; i < arr.length; i++) {

if (hash[arr[i]] == null) {

res.push(arr[i]);

hash[arr[i]] = true;

}

}

return res;

}

unique([1,2,{a:1},3,2,{a:1},[1,2],[1,2]]);

// 1, 2, {a: 1}, 3, [1, 2]

 

###数组去扁平化

 

数组的扁平化,就是将一个嵌套多层的数组array(嵌套可以是任何层数)转换为只有一层的数组

 

var arr = [1, 2, 3, [4, 3, [2, 7], 2], 5, [5, 9, 10], 7];

// 去扁平化后

arr = [1, 2, 3, 4, 3, 2, 7, 2, 5, 5, 9, 10, 7];

 

(1)循环递归实现

 

// for循环,如果子元素还是数组,则递归调用该方法

function flatten(arr) {

var rets = [];

for(var i = 0; i < arr.length; i ++) {

if (Array.isArray(arr[i])) {

rets = rets.concat(flatten(arr[i]));

} else {

rets.push(arr[i]);

}

}

return rets;

}

 

// 使用forEach

function flatten(arr) {

var rets = [];

arr && arr.forEach(function(item) => {

if (Array.isArray(item)) {

rets = rets.concat(flatten(item));

} else {

rets.push(item);

}

});

return rets;

}

 

(2)使用reduce简化代码

 

function flatten(arr) {

return arr.reduce(function(pre, item){

return pre.concat(Array.isArray(item) ? flatten(item) : item);

}, [])

}

 

(3)如果数组元素都为数字,则可以使用toString方法

 

function flatten(arr) {

var newArr = arr.toString().split(',');

return newArr.map(function(item){

return +item; // 将字符串转为数字

});

}

 

es6提供的新方法 flat(depth)

let a = [1,[2,3]];

a.flat(); // [1,2,3]

a.flat(1); //[1,2,3]

 

优缺点无非是速度问题,暂时忽略

 

##2.多种方式实现深拷贝、对比优缺点

 

参考资料:https://www.cnblogs.com/echolun/p/7889848.html

 

###1.我们怎么去实现深拷贝呢,这里可以递归递归去复制所有层级属性。

function deepClone(obj){

let objClone = Array.isArray(obj)?[]:{};

if(obj && typeof obj==="object"){

for(key in obj){

if(obj.hasOwnProperty(key)){

//判断ojb子元素是否为对象,如果是,递归复制

if(obj[key]&&typeof obj[key] ==="object"){

objClone[key] = deepClone(obj[key]);

}else{

//如果不是,简单复制

objClone[key] = obj[key];

}

}

}

}

return objClone;

}

let a=[1,2,3,4],

b=deepClone(a);

a[0]=2;

console.log(a,b);

 

###2.除了递归,我们还可以借用JSON对象的parse和stringify

function deepClone(obj){

let _obj = JSON.stringify(obj),

objClone = JSON.parse(_obj);

return objClone

}

let a=[0,1,[2,3],4],

b=deepClone(a);

a[0]=1;

a[2][0]=1;

console.log(a,b);

 

###3.除了上面两种方法之外,我们还可以借用JQ的extend方法。

$.extend( [deep ], target, object1 [, objectN ] )

 

deep表示是否深拷贝,为true为深拷贝,为false,则为浅拷贝

 

target Object类型 目标对象,其他对象的成员属性将被附加到该对象上。

 

object1 objectN可选。 Object类型 第一个以及第N个被合并的对象。

 

let a=[0,1,[2,3],4],

b=$.extend(true,[],a);

a[0]=1;

a[2][0]=1;

console.log(a,b);

 

##3.手写函数柯里化工具函数、并理解其应用场景和优势

参考资料:

https://blog.csdn.net/u011500781/article/details/80004517

https://www.cnblogs.com/guolao/p/10144086.html

 

##4.手写防抖和节流工具函数、并理解其内部原理和应用场景

 

参考资料:https://www.cnblogs.com/eggplants/p/9592563.html

 

在实际开发应用中,经常会碰到高频率的事件处理,比如 window 的 scroll, resize 以及 keyup,mousemove 等事件。

这些高频率的事件触发会带来一些显著的问题。 如果事件处理函数调用的频率无限制,会加重浏览器的负担,导致用户体验非常糟糕。

 

高频率的事件处理函数中,存在着大量的DOM操作,当浏览器的渲染速度跟不上事件触发频率,容易造成页面卡顿,影响用户体验,甚至会造成 CPU 使用率过高导致页面崩溃。

 

高频率的事件处理函数中,每执行一次事件处理函数时,都需要和服务器通信建立 HTTP 请求,比如页面的搜索功能,那么可能存在短时间内发起了数十条 HTTP 请求的情况,容易消耗服务器资源。

 

针对这些问题的解决方案,可以采用函数防抖(debounce)和节流(throttle)的方案解决存在的问题,通过防抖和节流可以将多个事件的触发合并成一个,减少事件触发频率。 同时又不影响实际效果。

 

function debounce(fn, wait) {

var timeout = null;

return function() {

if(timeout !== null)

clearTimeout(timeout);

timeout = setTimeout(fn, wait);

}

}

// 处理函数

function handle() {

console.log(Math.random());

}

// 滚动事件

window.addEventListener('scroll', debounce(handle, 1000));

 

##5.实现一个sleep函数

 

参考资料:https://www.cnblogs.com/mengfangui/p/9765243.html

 

//方法一

function sleep1(ms, callback) {

setTimeout(callback, ms)

}

//sleep 1s

sleep1(1000, () => {

console.log(1000)

})

//方法二

function sleep2(ms) {

return new Promise(function(resolve, reject) {

setTimeout(resolve, ms)

})

}

sleep2(1000).then(() => {

console.log(2000)

})

//方法三

function sleep3(ms) {

return new Promise(function(resolve, reject) {

setTimeout(resolve, ms)

})

}

async function init() {

await sleep3(1000);

}

init().then(() => {

console.log(3000)

})

 


最新回复(0)