天天看點

一名【合格】前端工程師的自檢清單(JavaScript編碼能力篇)#JavaScript編碼能力

#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)

})

繼續閱讀