久久综合九色综合97婷婷-美女视频黄频a免费-精品日本一区二区三区在线观看-日韩中文无码有码免费视频-亚洲中文字幕无码专区-扒开双腿疯狂进出爽爽爽动态照片-国产乱理伦片在线观看夜-高清极品美女毛茸茸-欧美寡妇性猛交XXX-国产亚洲精品99在线播放-日韩美女毛片又爽又大毛片,99久久久无码国产精品9,国产成a人片在线观看视频下载,欧美疯狂xxxx吞精视频

有趣生活

當前位置:首頁>職場>前端開發100個面試題(2022年前端核心手寫面試題)

前端開發100個面試題(2022年前端核心手寫面試題)

發布時間:2024-01-24閱讀(14)

導讀<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"></head><body>防抖:<input....

<!DOCTYPE html> <html lang="en"><head> <meta charset="UTF-8"></head><body> 防抖: <input id="input" type="text"></body><script> // 監聽拿到input輸入的值 input.addEventListener(input, Function (e) { val(e.target.value) }) // 防抖的核心代碼 function fn(time, fun) { let flag // 定義狀態 return function (value) { clearTimeout(flag)// 在執行之前 清除 定時器的 flag 不讓他執行 flag = setTimeout(() => { fun(value) }, time) } } let val = fn(1000, function (val) { console.log(val) })</script></html>,今天小編就來聊一聊關于前端開發100個面試題?接下來我們就一起去研究一下吧!

前端開發100個面試題(2022年前端核心手寫面試題)

前端開發100個面試題

防抖

<!DOCTYPE html> <html lang="en"><head> <meta charset="UTF-8"></head><body> 防抖: <input id="input" type="text"></body><script> // 監聽拿到input輸入的值 input.addEventListener(input, Function (e) { val(e.target.value) }) // 防抖的核心代碼 function fn(time, fun) { let flag // 定義狀態 return function (value) { clearTimeout(flag)// 在執行之前 清除 定時器的 flag 不讓他執行 flag = setTimeout(() => { fun(value) }, time) } } let val = fn(1000, function (val) { console.log(val) })</script></html>

節流

<body> <button id="button">手在快1秒執行一次</button></body><script> /* 定時器版本的 fns 回調函數 time 間隔時間 function throttle(fns, time) { let flag // 定義一個空狀態 return function () { // 內部函數訪問外部函數形成閉包 if (!flag) { // 狀態為空執行 flag = setTimeout(() => { fns.apply(this, arguments) // 改變this指向 吧 event 事件對象傳出去 flag = null }, time) } } } */ function throttle(fun, time) { let flag = 0 return function () { let now = new Date().valueOf() // 當前的值 減去上一次的值 >= 傳過來的事件 執行 if (now - flag >= time) { fun.apply(this, arguments) flag = now } } } button.onclick = throttle((e) => { console.log(e) }, 1000)</script>

深拷貝

var arr = { a: 2, b: [33] } function cloneDeep(arr = {}) { // 終止遞歸 判斷如果傳進來的數據不是 object 或者 傳進來的是一個 null 直接返回 if (!arr || typeof arr != object || arr == null) return arr // 聲明一個對象 let result // 用 instanceof 判斷原型鏈上是否有該類型的原型 是 Array => [] ! Arrays =>{} arr instanceof Array ? result = [] : result = {} // forin 循環對象的key值 for (const key in arr) { // 對象 key 賦值 result result[key] = cloneDeep(arr[key]) } return result } let arr2 = cloneDeep(arr) // let arr2 = [...arr] arr2.b[0] = 5 console.log(arr);// {a: 2, b: Array(1)} Array a: 2 b: [33] console.log(arr2);// {a: 2, b: Array(1)} Array a: 2 b: [5] // 修改新對象不影響原來的對象

類型判斷

/*實現一個類型判斷 [] 返回 array {} 返回object /^$/ RegExp 1 number */ // 第一種方案 function type_of(obj) { let res = Object.prototype.toString.call(obj).split( )[1] // 輸出 RegExp] /* res.substring(0, res.length - 1) 從第 0 項開始截取 截取到它的長度 -1 也就是最后一項的前一項 把最后的一項 ] 給干掉 */ return res.substring(0, res.length - 1).toLowerCase() } // 第二種方案 function type_of(obj) { // .slice(8, -1) 從 第 8項開始截取 -1 不要最后一項 return Object.prototype.toString.call(obj).slice(8, -1).toLowerCase() }

數字千位分割

const format = (n) => { let num = n.toString() // 拿到傳進來的 number 數字 進行 toString let len = num.length // 在拿到字符串的長度 // 當傳進來的結果小于 3 也就是 千位還把結果返回出去 小于3 不足以分割 if (len < 3) { return num } else { let render = len % 3 //傳入 number 的長度 是否能被 3 整除 console.log(render) /* match() 方法可在字符串內檢索指定的值,或找到一個或多個正則表達式的匹配。 該方法類似 indexOf() 和 lastIndexOf(),但是它返回指定的值,而不是字符串的位置。 var str = 123123000 str.match(/w{3}/g).join(,) // 123,123,000 */ if (render > 0) { // 說明不是3的整數倍 return num.slice(0, render) , num.slice(render, len).match(/d{3}/g).join(,) } else { return num.slice(0, len).match(/d{3}/g).join(,) } } } let str = format(298000) console.log(str)

生成隨機數

// 生成隨機數function random(min, max) { // Math.floor() 向下進行取證 return Math.floor(Math.random() * (max - min 1) min) } console.log(random(3, 5))

輪詢方法的封裝

const pollFetch = async (callback,pollingInterval,delayTimeStatus = false,stop = false) => { if(stop) return const timeoutPromise = (delayTime) => { return new Promise(resolve => { window.timeId = setTimeout(resolve, delayTime); }) } while (true) { const pollingTime = 1 * pollingInterval; const delayTime = pollingTime (1000 * parseInt(Math.random() * 40, 10)); // 輪詢時間間隔 try { await callback(); await timeoutPromise(delayTimeStatus ? delayTime : pollingTime); } catch (e) { await timeoutPromise(delayTimeStatus ? delayTime : pollingTime); } }}/* pollFetch(()=> {},1000,true) @ callback 回調 必穿 任務隊列 @ pollingInterval 1000 == 一秒 必穿 輪詢時間打印服務器的 @ delayTimeStatus 不布爾 非必穿 延遲的狀態 @ stop 布爾 菲必傳 停止定時器 */pollFetch(() => { return new Promise((resolve, reject) => { setTimeout(() => { resolve(); console.log(4243242342) }, 50); })},200,false,false)

手寫call方法

// 給function的原型上面添加一個 _call 方法Function.prototype._call = function (context) { // 判斷調用者是否是一個函數 this 就是調用者 if (typeof this != function) { return } // 如果有 context 傳參就是傳參者 沒有就是window that = context || window // 保存當前調用的函數 that.fn = this // 吧 this == fns 存到that.fn來 // 截取傳過來的參數 /* arguments a: 1 fn: ? fns() */ // 通過 slice 來截取傳過來的參數 const local = [...arguments].slice(1) // 傳入參數調用函數 let result = that.fn(...local) // 刪出 fn 屬性 delete that.fn return result } let obj = { a: 1 } function fns(a, b) { console.log(a, b); console.log(this) } fns._call(obj, 23, 555)

手寫apply

Function.prototype.myApply = function (context) { if (typeof this !== function) { // 判斷當前調用者是否為函數 return } // 保存傳入的this指向 that = context || window // 保存當前調用的函數 that.fn = this let result // 這里開始判斷傳入的參數是否存在,此時參數是一個數組形式[thisArg,[傳參]] // 那么如果arguments[1]即傳參存在的時候,就是需要傳參調用保存的函數 // 如果不存在就直接調用函數 if (arguments[1]) { result = that.fn(...arguments[1]) } else { result = that.fn() } return result } let obj = { a: 1 } function fn(...val) { console.log(this) console.log(...val) } fn.apply(obj, [1, 4, 5, 6, 7, 9])

手寫 bind

Function.prototype._bind = function (context) { // 當調用用了_bind 函數 this 指向調用 _bind 的那個函數 // this 不是 function 不讓使用 拋出類型錯誤 if (typeof this != function) { throw new TypeError(Error) } // 獲取參數 除了傳過來的第一項我全都要 const args = [...arguments].slice(1) // 吧 function 進行一個緩存 fn = this // 返回一個函數 因為 bind 不是立即調用的 return function Fn() { // 判斷 this 原型鏈上是否又該類型的原型 Fn return fn.apply(this instanceof Fn ? new fn(...arguments) : context, args.concat(...arguments)) } } let obj = { a: 1 } function fn(...val) { console.log(this) // obj console.log(...val) // 231, 31242344, 432 } fn._bind(obj, 231, 31242344, 432)()

數組去重

/* 數組的去重 */let ylbsz = [1, 35, 6, 78, 66, 6, 35] function _set(arr) { // 放一個新數組 let newArr = [] for (let i = 0; i < arr.length; i ) { if (newArr.indexOf(arr[i]) == -1) { newArr.push(arr[i]) } } return newArr } console.log(_set(ylbsz)) console.log([...new Set([11, 11, 222, 222])]) // 字符串去重 let str = 123321你好你好 console.log([...new Set(str.split())].join())

數組排序(冒泡)

function sort(arr) { // 外層循環控制的是比較的輪數,你要循環幾輪 // arr.length (5 ) - 1 = 4 for (let i = 0; i < arr.length - 1; i ) { // 內層循環控制的每一輪交換的次數 // 第一輪要比較4次 下標為 0 arr.length - 1(4) - i(0) = 4 // 第二輪要比較3次 下標為 1 arr.length - 1(4) - i(1) = 3 // 第三輪要比較2次 下標為 2 arr.length - 1(4) - i(2) = 2 // 第四輪要比較1次 下標為 3 arr.length - 1(4) - i(3) = 1 // 內層循環控制的每一輪交換的次數 for (let j = 0; j < arr.length - 1 - i; j ) { // arr[j] 第一項 arr[j 1] 第二項 // arr[j] 第二項 arr[j 1] 第三項 // .... if (arr[j] > arr[j 1]) { // 大于后一項 做一個交換變量 es6 結構賦值 的變量交換 [arr[j], arr[j 1]] = [arr[j 1], arr[j]] } } } return arr } console.log(sort([200, 100, 3, 9, 4]));

數組的排序(快排)

let arr = [1, 4, 6, 7, 7, 9] // 1. 取出我們數組的中間項 用splice 拿到中間項 // 2. 在聲明兩個空數組,一個空數組用來放置 中間一項 大于 循環的每一項的話 就把他放到左邊的數組里,下 // 余的話就放到右邊的數組 // 3.接下來就是循環便利了 // 最后再次利用函數自己調用自己一直執行 遞歸 // 4. 如果傳進來的數組 小于等于 1 的話就終止遞歸循環 // 做一個快排 function fn(arr) { // 如果傳進來的數組 小于等于 1 的話就終止遞歸循環 if (arr.length <= 1) return arr // 總長度除以2的話就可以拿到中間一項的下標 let n = Math.floor(arr.length / 2) // splice 返回被刪除的元素 下標為 0 就是只拿第一項 因為它只返回一個數據 就是被刪除的一項 let cen = arr.splice(n, 1)[0] // 2. 在聲明兩個空數組,一個空數組用來放置 中間一項 大于 循環的每一項的話 就把他放到左邊的數組里,下 // 余的話就放到右邊的數組 let leftArr = [] let rightArr = [] // 接下來就是循環便利了 判斷 for (let j = 0; j < arr.length; j ) { let item = arr[j] // > 如果是大于就是 從大到小 如果是小于 < 從小到大 cen < item ? rightArr.push(item) : leftArr.push(item) } return fn(leftArr).concat(cen, fn(rightArr)) } console.log(fn(arr))

數組排序(插入排序)

function insert(arr) { // 1、準備一個數組這個數組就是新抓的牌,開始先抓一張牌進來 let handle = [] handle.push(arr[0]) // 2、第二次開始按順序抓牌一直把牌抓光了 for (let i = 1; i < arr.length; i ) { // a 是新抓的牌 let a = arr[i] // 和手里的牌進行比較(從后向前比) // handle.length - 1 因為下標是從 0 開始數的 for (let j = handle.length - 1; j >= 0; j--) { // 每一次要比較手里的牌 let b = handle[j] // 如果當前新牌a比b 大了,可就要放到 b 的后面 // 如果 a > b 就是表示從小到大 // a < b 送大到小 if (a > b) { // 如果想要放到 j 的后面就要加上一個 1, /** * 比如說我要插隊一般要插就是插到 a 的前面 * 但是我想要插到 a 的后面怎么辦 * 那這個時候就要插到 a 下一個人的人前面就可以了 * */ handle.splice(j 1, 0, a) break } // 還有一種情況就是如果你比較到第一項的還比較嗎,不比較了 // 我們吧新牌放到最前面即可 if (j == 0) { handle.unshift(a) } } } return handle } console.log(insert([2, 8, 5, 92, 52, 4]))

數組的最大值最小值

const array = [5, 4, 7, 8, 9, 2]; let num = array.reduce((a, b) => a > b ? a : b); console.log(num) // 9 let nums = array.reduce((a, b) => a < b ? a : b); console.log(nums) // 2

對象去重

/*@ 數據處理對象去重*/ let arr = [ { a: 1, b: 2, id: 6666 }, { a: 1, b: 2, id: 6666 }, { a: 6, b: 8, id: 77777 }, { a: 8, b: 2, id: 88888 }, ] /* @ 輸出 : 0: { a: 1, b: 2, id: 6666 } 1: { a: 6, b: 8, id: 77777 } 2: { a: 8, b: 2, id: 88888 } */ function ssff(arr4, id) { var obj = {}; function deWeightFour() { arr4 = arr4.reduce(function (a, b) { obj[b.id] ? : obj[b.id] = true && a.push(b); return a; }, []) return arr4; } var newArr4 = deWeightFour(); return newArr4 } console.log(ssff(arr, id))

手寫 indexOf

~ function () { // 在函數前加上波浪號,其作用是把函數聲明轉換為表達式, // 就可以直接將下面的代碼放入某個函數里運行。 // 不用indexOf 和 includes function myIndexOf(a) { // 1、 這個也可以正則實現 下面代碼 // let reg = new RegExp(a) // res = reg.exec(this) // return res === nu ll ? -1 : res.index // 這個也可以正則實現 let lena = a.length y = this.length flag = -1 if (lena > y) return -1 // 如果輸入的字符串大于要檢測的字符串直接 -1 for (var i = 0; i <= y - lena; i ) { if (this.substr(i, lena) === a) { // substr() 方法可在字符串中抽取從 start 下標開始的指定數目的字符。 flag = i break } } return flag } String.prototype.myIndexOf = myIndexOf }() let demo = dwanlghMappaw let str = h console.log(demo.myIndexOf(str));

手寫 instanceof

// instanceof // 1、只要當前類出現在實例的原型上,結果都為 true // 2、由于我們可以肆意的修改原型的指向,所以檢測出來的結果是不準確的 // 3、不能檢測基本數據類型 var arr = [] console.log(arr); function instance_of(example, classFunc) { // 實例.__proto__ === 類.prototype => instanceof let classFuncPrototype = classFunc.prototype // 這個就代表類的原型 proto = Object.getPrototypeOf(example) // example.__proto__ 實例的.__proto__ while (true) { // 我也不知道你要找多少次 while循環 if (proto === null) { // 找到最頂層為null就說明沒找到 返回 false return false } if (proto === classFuncPrototype) { return true } proto = Object.getPrototypeOf(proto) } } console.log(instance_of(arr, Array)); console.log(instance_of(arr, Object)); console.log(instance_of(arr, RegExp));

怎么判斷兩個對象是否相等?

/*① 首先比較兩個對象的長度,如果長度不相等使flag為false,為不相等;② 如果長度相等那就遍歷對象1(對象2也可以),利用hasOwnProperty() 方法查看對象1中是否包含對象2中的屬性或者方法,如果不包含則使flag為false,為不想等。hasOwnProperty() 方法會返回一個布爾值,指示對象自身屬性中是否具有指定的屬性(也就是,是否有指定的鍵)。 ③ 接下來判斷兩對象的內存地址是否相同,不同則為true*/function compreObj(obj1, obj2) {var flag = true;function compre(obj1, obj2) {if (Object.keys(obj1).length != Object.keys(obj2).length) {flag = false;} else {for (let x in obj1) {if (obj2.hasOwnProperty(x)) {if (obj1[x] !== obj2[x]) {compre(obj1[x], obj2[x]);}} else {flag = false;}}}if (flag === false) {return false;} else {return true;}}return compre(obj1, obj2)}console.log(compreObj(對象1, 對象2));

如何快速讓字符串變成已千為精度的數字

var str = "10000000000";/*第一種:把數字轉換成字符串后,打散為數組,再從末尾開始,逐個把數組中的元素插入到新數組(result)的開頭。 每插入一個元素,counter就計一次數(加1),當counter為3的倍數時,就插入一個逗號,但是要注意開頭(i為0時)不需要逗號。最后通過調用新數組的join方法得出結果。*/String.prototype.toThousands = function(){var num = this;var result = [ ], counter = 0;num = (num || 0).toString().split();for (var i = num.length - 1; i >= 0; i--) {counter ;result.unshift(num[i]);if (!(counter % 3) && i != 0) { result.unshift(,); }}return result.join();}console.log(str.toThousands());/*第二種:通過正則表達式循環匹配末尾的三個數字,每匹配一次,就把逗號和匹配到的內容插入到結果字符串的開頭, 然后把匹配目標(num)賦值為還沒匹配的內(RegExp.leftContext)。如果數字的位數是3的倍數時,最后一次匹配到的內容肯定是三個數字,但是最前面的三個數字前不需要加逗號;如果數字的位數不是3的倍數,那num變量最后肯定會剩下1到2個數字,循環過后,要把剩余的數字插入到結果字符串的開頭。*/function toThousands(num) {var num = (num || 0).toString(), re = /d{3}$/, result = ;while ( re.test(num) ) {result = RegExp.lastMatch result;if (num !== RegExp.lastMatch) {result = , result;num = RegExp.leftContext;} else {num = ;break;}}if (num) { result = num result; }return result;}console.log(toThousands(str)); 第三種:第二種的改良版function toThousands(num) {var num = (num || 0).toString(), result = ;while (num.length > 3) {result = , num.slice(-3) result;num = num.slice(0, num.length - 3);}if (num) { result = num result; }return result;}console.log(toThousands(str)); 第四種:懶人版function toThousands(num) {return (num || 0).toString().replace(/(d)(?=(?:d{3}) $)/g, $1,);}console.log(toThousands(str));

如何判斷JS對象中是否存在循環引用

我個人的理解是,如果一個對象的值等于父級(祖父級,曾祖父級…),則說明是循環引用了

定義一個空數組嗎,且對于目標對象進行遞歸,每次都判斷遞歸項是否為對象,是的話就放到數組里,而且每次判斷屬性值是否存在,在的話說明環引用了

function cycle(obj, parent) { //表示調用的父級數組 var parentArr = parent || [obj]; for (var i in obj) { if (typeof obj[i] === "object") { //判斷是否有循環引用 parentArr.forEach((pObj) => { if (pObj === obj[i]) { obj[i] = "[cycle]" } }); cycle(obj[i], [...parentArr, obj[i]]) } } return obj;}/**@2方法*/function hasLoop(obj){// 判斷對象內部是否有和源相同的屬性function findLoop(target, src){// 源數組,并將自身傳入const source = src.slice().concat([target])for(const key in target){// 如果是對象才需要判斷if(typeof target[key] === object){// 如果在源數組中找到 || 遞歸查找內部屬性找到相同if(source.indexOf(target[key]) > -1 || findLoop(target[key], source)){return true}}}return false}// 如果傳入值是對象,則執行判斷,否則返回falsereturn typeof obj === object ? findLoop(obj, []) : false}

簡易版Promise.all

function PromiseAll(promiseArray) { //返回一個Promise對象 return new Promise((resolve, reject) => { if (!Array.isArray(promiseArray)) { //傳入的參數是否為數組 return reject(new Error(傳入的參數不是數組!)) } const res = [] let counter = 0 //設置一個計數器 for (let i = 0; i < promiseArray.length; i ) { Promise.resolve(promiseArray[i]).then(value => { counter //使用計數器返回 必須使用counter res[i] = value if (counter === promiseArray.length) { resolve(res) } }).catch(e => reject(e)) } }) } const s1 = new Promise((res, rej) => { setTimeout(() => { res(p1) }, 1000) }) const s2 = new Promise((res, rej) => { setTimeout(() => { res(p2) }, 2000) }) const s3 = new Promise((res, rej) => { setTimeout(() => { res(p3) }, 3000) }) const test = PromiseAll([s1,s2, s3]) .then(res => console.log(res)) .catch(e => console.log(e)) console.log(test);

一維數組轉換 tree 結構

let arr = [ { id: 1, name: 部門1, pid: 0 }, { id: 2, name: 部門2, pid: 1 }, { id: 3, name: 部門3, pid: 1 }, { id: 4, name: 部門4, pid: 3 }, { id: 5, name: 部門5, pid: 4 }, ] // // 上面的數據轉換為 下面的 tree 數據 // [ // { // "id": 1, // "name": "部門1", // "pid": 0, // "children": [ // { // "id": 2, // "name": "部門2", // "pid": 1, // "children": [] // }, // { // "id": 3, // "name": "部門3", // "pid": 1, // "children": [ // { // id: 4, // name: 部門4, // pid: 3, // "children": [ // { // id: 5, // name: 部門5, // pid: 4, // "children": [] // }, // ] // }, // ] // } // ] // } // ] function tree(items) { // 1、聲明一個數組和一個對象 用來存儲數據 let arr = [] let obj = {} // 2、for of 便利我么傳進來的一個數據,給當前的數據添加children 屬性為 array 把他放到我們的obj對象里面 for (let item of items) { obj[item.id] = { ...item, children: [] } } // 3、for of 再次便利然后邏輯處理 for (let item of items) { // 4、把數據里面的id 取出來賦值 方便下一步的操作 let id = item.id let pid = item.pid // 5、根據 id 將 obj 里面的每一項數據取出來 let treeitem = obj[id] // 6、如果是第一項的話 吧treeitem 放到 arr 數組當中 if (pid === 0) { // 把數據放到 arr 數組里面 arr.push(treeitem) } else { // 如果沒有 pid 找不到 就開一個 obj { } if (!obj[pid]) { obj = { children: [] } } // 否則給它的 obj 根基 pid(自己定義的下標) 進行查找 它里面的children屬性 然后push obj[pid].children.push(treeitem) } } // 返回處理好的數據 return arr } console.log(tree(arr))

proxy 實現數據綁定

<!DOCTYPE html> <html lang="en"><head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title></head><body> <li id="li"></li> <input id="search" type="text"></body><script> let obj = {} obj = new Proxy(obj, { get(target, prop) { return target[prop] console.log(target,prop) }, set(target, prop, value) { console.log(target, prop, value) target[prop] = value observer() } }) function observer() { li.innerHTML = obj.name search.value = obj.name } setTimeout(() => { obj.name = 孫志豪 }, 1000) search.oninput = function () { obj.name = this.value }</script></html>

思考題 LazyMan

// LazyMan(Hank);// 輸出: // Hi! This is Hank! // LazyMan(Hank).sleep(3).eat(dinner) // 輸出: // Hi! This is Hank! // //等待3秒.. // Wake up after 3 // Eat dinner~ // LazyMan(Hank).eat(dinner).eat(supper) // 輸出: // Hi This is Hank! // Eat dinner~ // Eat supper~ // LazyMan(Hank).sleepFirst(2).eat(dinner).sleep(3).eat(supper) // 輸出: // 等待2秒.. // Wake up after 2 // Hi This is Hank! // Eat dinner~ // 等待3秒.. // Wake up after 3 // Eat supper~ // function LazyMan(arr) { // return Hi! This is arr // } // console.log(LazyMan(Hank)) function LazyMan(params) { // 聲明一個數組 let arr = [] // 這是第一個的輸出結果 const fn = () => { console.log(`Hi This is ${params}!`), next() } // 聲明一個方法用來控制是否執行下一項 const next = () => { // 返回刪除后的第一個數組 const fn = arr.shift() // 如果第一項在就去執行第一個 fn && fn() } // 吧第一個輸出放到數組中 arr.push(fn) // 上來執行一次,是最快執行但不是立馬執行 setTimeout(() => { next() }) // 聲明一個對象給 拋出去 let api = { sleepFirst: (content) => { //因為這結果是是第一個執行 所以用 unshift arr.unshift(() => { setTimeout(() => { console.log(Wake up after content); next() }, content * 1000) }) return api }, eat: (content) => { // 這個是后面的執行的 arr.push(() => { console.log(`Eat ${content}~`) next() }) return api }, sleep: (content) => { // 延遲并最后執行 arr.push(() => { setTimeout(() => { console.log(Wake up after content); next() }, content * 1000) }) return api }, } return api } LazyMan(Hank).sleepFirst(2).eat(dinner).sleep(3).eat(supper)

思考題 1 某公司1 - 12 月的營業額

/*** * @ sun 完成一下需求某公司1 - 12 月的營業額 存放在一個對象里面如一下: * let obj = { 1: 888, 2: 542, 5: 637 } 請把數據處理成為 : [888, 542, null, null, 637, null, null, null, null, null, null, null] * * */第一種方案 let arr = new Array(12).fill(null).map((item, index) => { return obj[index 1] || null }) console.log(arr)//第二種方案Array.from(arr) 把對象變為一個數組 前提就是必須要有 length 的屬性 arr.length = 13 obj.length = 13 let result = Array.from(obj).slice(1).map(item => { return typeof item == undefined ? null : item }) console.log(result)//第三種方案//創建一個12項為 null 的數組 let arr = new Array(12).fill(null) // Object.keys(obj) 獲取 obj 的key值 Object.keys(obj).forEach(item => { // 這個 -1 就把下標減去一個 arr[item - 1] = obj[item] }) console.log(arr)

思考題 2 實現 5.add(3).minus(2), 輸出結果為 6

/** * @ 思考題 * 實現 5.add(3).minus(2), 輸出結果為 6 * add調用 加法 minus調用 減法 */ ~function () { // 每一個方法執行完都會返回一個 number 這類的實例, 這樣就可以繼續調用number類原型中的方法(鏈式寫法) function check(n) { n = Number(n) return isNaN(n) ? 0 : n } function add(n) { console.log(this) // this 就是誰調用我this 就是誰 n = check(n) return this n } function minus(n) { n = check(n) return this - n } // Number.prototype.add = add // Number.prototype.minus = minus // 方法多的情況下簡寫 [add, minus].forEach(element => { // eval() 函數會將傳入的字符串當做 JavaScript 代碼進行執行。 Number.prototype[element] = eval(element) }); }() // 由于不能以數字開頭 必須加上圓括號 console.log((5).add(3).minus(2))

思考題3 大寫轉為小寫小寫轉為大寫

/* * @ 這里有一個字符串需要將它吧大寫轉為小寫小寫轉為大寫 * let str = sUnZHIhaO */ // charCodeAt(N) 返回在指定的位置的字符的 Unicode 編碼 let str = sUnZHIhaO function fn(val) { return val.replace(/[a-zA-Z]/g, config => { // config 每一次正則匹配的結果 // charCodeAt a ==65 z ==90 判斷是否大小寫 config.charCodeAt() >= 65 && config.charCodeAt() <= 90 // 驗證字母大小寫:把字母轉換為大寫,看原來的是否是大寫,如果是就轉換為小寫,不是還是原來 return config.toUpperCase() === config ? config.toLowerCase() : config.toUpperCase() }) console.log(val) } console.log(fn(sUnZHIhaO))

思考題4 找一個字符串中重復最多一項和重復一項的字符串的最多個數

/* var str = abcabcddkkkk @ 查找一個字符串中重復最多一項和重復一項的字符串的最多個數 輸出 k4 */ var str = abcabcddkkkk function func(str) { let obj = {} // 聲明一個對象 for (let i = 0; i < str.length; i ) { let item = str[i] // obj[item] = 如果中間有重復的 obj[item] 就讓他 1 沒有重復的話就 直接返回 1 obj[item] = obj[item] 1 || 1 } // 聲明兩個變量一個 max_num是重復最對的個數 重復max_key 以這個是key var max_key, max_num = 0 // for in 用來便利對象拿到的是key值 for (const key in obj) { if (max_num < obj[key]) { // 拿到value 值賦值 max_num max_num = obj[key] // 拿到 key 賦值給 max_keys max_key = key } } return `${max_key}${max_num}` } console.log(func(str))

思考題5 單個大寫字母排到最后

/* 輸入: let arr = [A1, B1, A2, B2] let str = [A, B] 輸出: [A1, B1, A, A2, B2, B] */ let arr = [A1, A2, B1, B2] let str = [A, B] // // 加上一個 Z 可以讓當前數據排到最后 // str = str.map(item => item Z) // // localeCompare() 方法返回一個數字來指示一個參考字符串是否在排序順序前面或之后或與給定字符串相同。 // let obj = arr.concat(str).sort((a, b) => a.localeCompare(b)).map(item => item.replace(Z, )) // console.log(obj) // 循環 str 拿到每一項 let k = 0 // 循環兩遍 for (let i = 0; i < str.length; i ) { let item1 = str[i] for (let j = 0; j < arr.length; j ) { let item2 = arr[j] if (item2.includes(item1)) { // 如果包含就記錄一下當前的位置(后面還有包含的會重新記錄的這個值) k = j } } // 把當前項插入arr到后面 arr.splice(k 1, 0, item1) } console.log(arr)

思考題6要求重新排序為數字在后字母在前

/* @ 14575476a1b2c309lmcsa89908pppkdgvkkllhijkldddefgklmnopqrstuywxyz 輸出 Abcdefghijklmnopqrstuvwxyz9876543210 */ let str = 14575476a1b2c309lmcsa89908pppkdgvkkllhijkldddefgklmnopqrstuywxyz console.log([...new Set(str.replace(/[^a-zA-Z]/g, ).split().sort().concat([...str.replace(/[^d]/g, )].sort().reverse()))].join().replace(/( |^)[a-z]/g, (L) => L.toUpperCase())) /* @ 有一個字符串‘a1b2c309pppkkk’ 要求重新排序為數字在后字母在前 且首字母大寫,數字需要倒序排列,最后整體字符串去重。 */ let a = str.replace(/[^a-zA-Z]/g, ) // 拿到所有的字母 let b = str.match(/[0-9]/g).reverse().join() // 拿到所有的數字進行 反轉 console.log([...new Set(a b)].join().replace(str[0], str[0].toUpperCase()))

思考題 處理數組的屬性名

let arr = [數據1, 數據2] let obj = [ [213, 56465], [21342, 769], ]/* 處理為一下 let ff = [ { 數據1: 213, 數據2: 56465 }, { 數據1: 21342, 數據2: 769 }, ]*/ function toHash(array, data) { // 定義一個空數組 因為 期望數據最層是一個數組 let reslute = [] // 循環傳進來的需要處理的數據 data.forEach((item, index) => { // 每一次便利都要想這個對象里面添加數據 let obj = {} // 循環data數據里面的每一項每一項是個數組 item.forEach((val, i) => { // obj 對應的屬性名對應 array 下標的每一項 obj[array[i]] = val }) // 根據 data 的下標為每一項添加內層循環處理好的對象 reslute[index] = obj }) return reslute } console.log(toHash(arr, obj))

思考題 保留兩位小數

function round(num, decimal) { if (isNaN(num)) { return 0 } const p1 = Math.pow(10, decimal 1) const p2 = Math.pow(10, decimal) return Math.round(num * p1 / 10) / p2 } console.log(round(21.436,2)) // 21.44

思考題 計算總價格的封裝 并且保留小數

/** * 取數組的之和,或對象數組中指定屬性的之和 并且保留 3 三位小數 * @method sum * @param {String} attr 對象數組的屬性 * @return {Integer} result 之和 * @example * let a=[1,2,3,4] * DictArray.$(a).sum();//==>10. * let a=[{age:1,name:"n1"},{age:3,name:"n2"}]; * DictArray.$(a).sum("age");//==>4. */ function round(num, decimal) { if (isNaN(num)) { return 0 } const p1 = Math.pow(10, decimal 1) const p2 = Math.pow(10, decimal) return Math.round(num * p1 / 10) / p2 } class DictArray { data; constructor(data) { this.data = data } sum(attr, accuracy = 2) { let res = this.data.filter(item => item != null) let ress = attr ? res.reduce((r, item) => r Number(item[attr]), 0) : res.reduce((r, item) => r = Number(item), 0) return round(ress, accuracy) } static $(arr) { let res = new DictArray(arr) return res } } let a = [{ age: 1.4444, name: "n1" }, { age: 3.7765, name: "n2" }]; console.log(DictArray.$(a).sum(age, 3))

還有很多,后續持續更新,這些都是自己面試或者問了一些大廠的朋友,希望對對大家有用,祝各位面試順利,感謝給位的觀看,喜歡的點個贊吧

TAGS標簽:  前端  開發  100個  試題  2022年  前端開發100個面試

Copyright ? 2024 有趣生活 All Rights Reserve吉ICP備19000289號-5 TXT地圖HTML地圖XML地圖