每道題都寫(xiě)多種解法,開(kāi)闊思路。一共45道題。
因?yàn)榕?途W(wǎng)oj不支持ES6語(yǔ)法,所以大多數(shù)寫(xiě)法只給出傳統(tǒng)寫(xiě)法。
題目描述
找出元素 item 在給定數(shù)組 arr 中的位置
輸出描述:
如果數(shù)組中存在 item,則返回元素在數(shù)組中的位置,否則返回 -1
輸入例子:
indexOf([ 1, 2, 3, 4 ], 3)
輸出例子:
2
// 一般寫(xiě)法 function indexOf(arr, item) { for (var i = 0; i < arr.length; ++i) { if (item === arr[i]) { return i; } } return -1; } // 簡(jiǎn)單粗暴版(因?yàn)閖s自帶的indexOf函數(shù)功能已經(jīng)實(shí)現(xiàn)了) function indexOf(arr, item) { return arr.indexOf(item); } // 每次比較后都將數(shù)組首元素去掉,同時(shí)計(jì)數(shù)器加1,直到找到元素item function indexOf(arr, item) { var count = 0, len = arr.length; while (arr.length !== 0 && arr[0] !== item) { arr.shift(); count++; } return count === len ? -1 : count; } // 較復(fù)雜的寫(xiě)法(不建議使用) function indexOf(arr, item) { var pos = arr.map(function(e, index) { return e === item ? index: -1; }).filter(function(e) { return e !== -1; }); return pos.length === 0 ? -1 : pos[0]; } // forEach加try-catch語(yǔ)句(不建議使用) function indexOf(arr, item) { try { arr.forEach((e, i) => { if (e === item) { throw new Error(i); } } catch (err) { return err.message; } return -1; } }
題目描述
計(jì)算給定數(shù)組 arr 中所有元素的總和
輸入描述:
數(shù)組中的元素均為 Number 類(lèi)型
輸入例子:
sum([ 1, 2, 3, 4 ])
輸出例子:
10
// 一般寫(xiě)法 function sum(arr) { var sum = 0; for (var i = 0; i < arr.length; ++i) { sum += arr[i]; } return sum; } // 使用reduce,且將sum初始化為0 function sum(arr) { return arr.reduce(function(sum, e) { return sum + e; }, 0); } // ES6寫(xiě)法,且將reduce中傳的0省略,則sum在這里相當(dāng)于初始化為arr的首元素 //【第一個(gè)sum為函數(shù)名,其余為函數(shù)內(nèi)變量名】 const sum = (arr) => arr.reduce((sum, e) => sum + e);
題目描述
移除數(shù)組 arr 中的所有值與 item 相等的元素。不要直接修改數(shù)組 arr,結(jié)果返回新的數(shù)組
輸入例子:
remove([1, 2, 3, 4, 2], 2)
輸出例子:
[1, 3, 4]
// 一般寫(xiě)法 function remove(arr, item) { var tempArr = []; for (var i = 0; i < arr.length; ++i) { tempArr.push(arr[i]); } /* 對(duì)arr的拷貝可使用一個(gè)技巧,即 tempArr = arr.slice(0); 以后均采用這種寫(xiě)法*/ var index = tempArr.indexOf(item); while (index !== -1) { tempArr.splice(index, 1); // 每次刪一個(gè)元素 index = tempArr.indexOf(item); } return tempArr; } // 使用filter function remove(arr, item) { return arr.filter(function(e) { return e !== item; }); }; // ES6寫(xiě)法 const remove = (arr, item) => arr.filter((e) => e !== item);
移除數(shù)組 arr 中的所有值與 item 相等的元素,直接在給定的 arr 數(shù)組上進(jìn)行操作,并將結(jié)果返回
輸入例子:
removeWithoutCopy([1, 2, 2, 3, 4, 2, 2], 2)
輸出例子:
[1, 3, 4]
// 一般寫(xiě)法 function removeWithoutCopy(arr, item) { for (var i = 0; i < arr.length; ++i) { if (arr[i] === item) { arr.splice(i, 1); i--; }; }; return arr; } // 類(lèi)似地 function removeWithoutCopy(arr, item) { var index = arr.indexOf(item); while (index !== -1) { arr.splice(index, 1); index = arr.indexOf(item); } return arr; } /* 因?yàn)閒ilter會(huì)改變不修改數(shù)組本身,會(huì)返回一個(gè)新數(shù)組,所以此處不采用 */
題目描述
在數(shù)組 arr 末尾添加元素 item。不要直接修改數(shù)組 arr,結(jié)果返回新的數(shù)組
輸入例子:
append([1, 2, 3, 4], 10)
輸出例子:
[1, 2, 3, 4, 10]
function append(arr, item) { var tempArr = arr.slice(0); tempArr.push(item); return tempArr; }
題目描述
刪除數(shù)組 arr 最后一個(gè)元素。不要直接修改數(shù)組 arr,結(jié)果返回新的數(shù)組
輸入例子:
truncate([1, 2, 3, 4])
輸出例子:
[1, 2, 3]
// 一般寫(xiě)法 function truncate(arr) { var tempArr = arr.slice(0); tempArr.splice(arr.length - 1); return tempArr; } // 使用pop function truncate(arr) { var tempArr = arr.slice(0); tempArr.pop(); return tempArr; }
題目描述
在數(shù)組 arr 開(kāi)頭添加元素 item。不要直接修改數(shù)組 arr,結(jié)果返回新的數(shù)組
輸入例子:
prepend([1, 2, 3, 4], 10)
輸出例子:
[10, 1, 2, 3, 4]
// 使用splice添加元素 function prepend(arr, item) { var tempArr = arr.slice(0); tempArr.splice(0, 0, item); return tempArr; } // 直接使用unshift添加首元素方法 function prepend(arr, item) { var tempArr = arr.slice(0); tempArr.unshift(item); return tempArr; }
題目描述
刪除數(shù)組 arr 第一個(gè)元素。不要直接修改數(shù)組 arr,結(jié)果返回新的數(shù)組
輸入例子:
curtail([1, 2, 3, 4])
輸出例子:
[2, 3, 4]
// 使用splice刪除元素 function curtail(arr) { var tempArr = arr.slice(); tempArr.splice(0, 1); return tempArr; } // 直接使用shift刪除首元素方法 function curtail(arr) { var tempArr = arr.slice(); tempArr.shift(); return tempArr; }
題目描述
合并數(shù)組 arr1 和數(shù)組 arr2。不要直接修改數(shù)組 arr,結(jié)果返回新的數(shù)組
輸入例子:
concat([1, 2, 3, 4], ["a", "b", "c", 1])
輸出例子:
[1, 2, 3, 4, "a", "b", "c", 1]
// 簡(jiǎn)單粗暴版,js已實(shí)現(xiàn)此函數(shù)功能 function concat(arr1, arr2) { var tempArr = arr1.slice(0); return tempArr.concat(arr2); } // 直接將arr2中的元素一個(gè)個(gè)push function concat(arr1, arr2) { var tempArr = arr1.slice(0); arr2.forEach(function(e) { tempArr.push(e); }); return tempArr; } // 簡(jiǎn)化版,使用apply function concat(arr1, arr2) { var tempArr = arr1.slice(0); [].push.apply(tempArr, arr2); // 簡(jiǎn)寫(xiě)版,可替換成下面一行,數(shù)組原型方法 /* Array.prototype.push.apply(tempArr, arr2); */ return tempArr; }
題目描述
在數(shù)組 arr 的 index 處添加元素 item。不要直接修改數(shù)組 arr,結(jié)果返回新的數(shù)組
輸入例子:
insert([1, 2, 3, 4], "z", 2)
輸出例子:
[1, 2, "z", 3, 4]
// 使用splice添加元素 function insert(arr, item, index) { var tempArr = arr.slice(0); tempArr.splice(index, 0, item); return tempArr; }
題目描述
統(tǒng)計(jì)數(shù)組 arr 中值等于 item 的元素出現(xiàn)的次數(shù)
輸入例子:
count([1, 2, 4, 4, 3, 4, 3], 4)
輸出例子:
3
// 一般寫(xiě)法 function count(arr, item) { var count = 0; arr.forEach(function(e) { e === item ? count++ : 0; }); return count; } // 使用ES6的for...of循環(huán) function count(arr, item) { let cnt = 0; for (let e of arr) { e === item ? cnt++ : 0; } return cnt; } // 使用reduce,歸約寫(xiě)法 function count(arr, item) { return arr.reduce(function(cnt, e) { return cnt + (e === item ? 1 : 0); }, 0); } // 使用ES6箭頭函數(shù) const count = (arr, item) => arr.reduce((cnt, e) => cnt + (e === item ? 1 : 0), 0); // 使用filter,返回一個(gè)新數(shù)組,其長(zhǎng)度即為所求 const count = (arr, item) => arr.filter(e => e === item).length;
題目描述
找出數(shù)組 arr 中重復(fù)出現(xiàn)過(guò)的元素
輸入例子:
duplicates([1, 2, 4, 4, 3, 3, 1, 5, 3]).sort()
輸出例子:
[1, 3, 4]
關(guān)于indexOf與lastIndexOf的文檔
// 一般寫(xiě)法,排序之后判斷相鄰元素是否相等 function duplicates(arr) { var sortedArr = arr.sort(); var tempArr = []; for (var i = 0; i < sortedArr.length; ++i) { if (sortedArr[i] === sortedArr[i + 1] && tempArr.indexOf(sortedArr[i]) === -1) { tempArr.push(sortedArr[i]); } } return tempArr; } // indexOf和lastIndexOf的妙用 function duplicates(arr) { var tempArr = []; arr.forEach(function(e) { if (arr.indexOf(e) !== arr.lastIndexOf(e) && tempArr.indexOf(e) === -1) { tempArr.push(e); } }); return tempArr; } // 使用reduce function duplicates(arr) { var tempArr = []; arr.forEach(function(e) { tempArr[e] = (tempArr[e] === undefined ? 1 : tempArr[e] + 1); /* 計(jì)算每個(gè)元素出現(xiàn)次數(shù) */ }); return tempArr.reduce(function(ret, e, item) { if (e && e !== 1 && ret.indexOf(item) === -1) { ret.push(item); /* 當(dāng)元素存在,且出現(xiàn)次數(shù)不為1,且未push進(jìn)ret中時(shí)... */ } return ret; }, []); }
題目描述
為數(shù)組 arr 中的每個(gè)元素求二次方。不要直接修改數(shù)組 arr,結(jié)果返回新的數(shù)組
輸入例子:
square([1, 2, 3, 4])
輸出例子:
[1, 4, 9, 16]
// 一般寫(xiě)法 function square(arr) { var tempArr = []; arr.forEach(function(e) { tempArr.push(e * e); }); return tempArr; } // 使用map function square(arr) { return arr.map(function(e) { return e * e; }) } // ES6箭頭函數(shù)版 const square = arr => arr.map(e => e * e);
題目描述
在數(shù)組 arr 中,查找值與 item 相等的元素出現(xiàn)的所有位置
輸入例子:
findAllOccurrences("abcdefabc".split(""), "a").sort()
輸出例子:
[0, 6]
// 一般寫(xiě)法(類(lèi)C,不推薦) function findAllOccurrences(arr, item) { var tempArr = []; for (var i = 0; i < arr.length; i++){ if (arr[i] === item) { tempArr.push(i); } } return tempArr; } // 改進(jìn)版 function findAllOccurrences(arr, item) { var tempArr = []; arr.forEach(function(e, index) { e !== item || tempArr.push(index); }); return tempArr; } // 使用map和filter function findAllOccurrences(arr, item) { return arr.map(function(ele, index) { return ele === item ? index : -1; /* 樣例返回結(jié)果為[ -1, -1, -1, -1, -1, -1, -1, 0, 6 ] */ }).filter(function(e) { return e !== -1; /* 過(guò)濾掉 e === -1 的情況 */ }) } // ES6箭頭函數(shù)版 const findAllOccurrences = (arr, item) => arr.map((ele, index) => ele === item ? index : -1).filter(e => e !== -1);
題目描述
給定的 js 代碼中存在全局變量,請(qǐng)修復(fù)
function globals() { myObject = { name : "Jory" }; return myObject; }
/* 在JavaScript中,如果不使用var聲明變量,則該變量被視為全局變量。*/ // 直接加var (在ES6標(biāo)準(zhǔn)中,最好替換成const或let) function globals() { var myObject = { name : "Jory" }; return myObject; } // 把對(duì)象歸屬改為原型 function globals() { globals.prototype.myObject = { name : "Jory" }; return globals; } // 把對(duì)象改為匿名的 function globals() { return { name : "Jory" }; }
題目描述
請(qǐng)修復(fù)給定的 js 代碼中,函數(shù)定義存在的問(wèn)題
function functions(flag) { if (flag) { function getValue() { return "a"; } } else { function getValue() { return "b"; } } return getValue(); }
輸入例子:
functions(true)
輸出例子:
a
/* else中的語(yǔ)句相當(dāng)于將if中的function重寫(xiě),因此無(wú)論flag為何值,返回的方法始終為重寫(xiě)后的方 法。將方法賦值給一個(gè)變量,方法就不會(huì)被重寫(xiě) */ // 將方法賦值給一個(gè)變量 function functions(flag) { var getValue = null; if (flag) { getValue = function () { return "a"; } } else { getValue = function () { return "b"; } } return getValue(); } // 修改為閉包形式 function functions(flag) { if (flag) { return (function() { return "a"; })(); } else { return (function() { return "b"; })(); } } // 使用 ?: 判斷語(yǔ)句整合版 function functions(flag) { function getValue() { return flag ? "a" : "b"; } return getValue(); } // ES6箭頭函數(shù)形式(精簡(jiǎn)版) const functions = flag => flag ? "a" : "b";
題目描述
修改 js 代碼中 parseInt 的調(diào)用方式,使之通過(guò)全部測(cè)試用例
function parse2Int(num) { return parseInt(num); }
輸入例子:
parse2Int("12"); parse2Int("12px"); parse2Int("0x12")
輸出例子:
12; 12; 0
/* parseInt(string, radix); 當(dāng)參數(shù)radix的值為0,或沒(méi)有設(shè)置該參數(shù)時(shí),parseInt()會(huì)根據(jù) string 來(lái)判斷數(shù)字的基數(shù)。 如果string以"0x"開(kāi)頭,parseInt()會(huì)把string的其余部分解析為十六進(jìn)制的整數(shù)。 如果string以0開(kāi)頭,那么ECMAScript3允許parseInt()的一個(gè)實(shí)現(xiàn)把其后的字符解析為八進(jìn)制 或十六進(jìn)制的數(shù)字。如果string以1~9的數(shù)字開(kāi)頭,parseInt()將把它解析為十進(jìn)制的整數(shù) */ // 將所有輸入轉(zhuǎn)換成十進(jìn)制輸出 function parse2Int(num) { return parseInt(num, 10); }
題目描述
判斷 val1 和 val2 是否完全等同
function identity(val1, val2) { return val1 === val2; }
題目描述
實(shí)現(xiàn)一個(gè)打點(diǎn)計(jì)時(shí)器,要求
1、從 start 到 end(包含 start 和 end),每隔 100 毫秒 console.log 一個(gè)數(shù)字,每次數(shù)字增幅為 1
2、返回的對(duì)象中需要包含一個(gè) cancel 方法,用于停止定時(shí)操作
3、第一個(gè)數(shù)需要立即輸出
setTimeout和setInterval的語(yǔ)法相同。它們都有兩個(gè)參數(shù),一個(gè)是將要執(zhí)行的代碼字符串,還有一個(gè) 是以毫秒為單位的時(shí)間間隔,當(dāng)過(guò)了那個(gè)時(shí)間段之后就將執(zhí)行那段代碼。 不過(guò)這兩個(gè)函數(shù)還是有區(qū)別的,setInterval在執(zhí)行完一次代碼之后,經(jīng)過(guò)了那個(gè)固定的時(shí)間間隔,它還 會(huì)自動(dòng)重復(fù)執(zhí)行代碼,而setTimeout只執(zhí)行一次那段代碼。 window.setInterval("function", time); //設(shè)置一個(gè)超時(shí)對(duì)象,周期="交互時(shí)間" window.setTimeout("function", time); //設(shè)置一個(gè)超時(shí)對(duì)象,只執(zhí)行一次,無(wú)周期 /* 停止定時(shí) */ window.clearInterval(對(duì)象); // 清除已設(shè)置的setInterval對(duì)象 window.clearTimeout(對(duì)象); // 清除已設(shè)置的setTimeout對(duì)象setInterval setTimeout clearInterval() clearTimeout()
// 一般寫(xiě)法,使用setInterval function count(start, end) { console.log(start++); var timer = setInterval(function() { if (start <= end) { console.log(start++); } else { clearInterval(timer); } }, 100); return { cancel: function() { clearInterval(timer); } } } // 用setTimeout模擬setInterval,遞歸寫(xiě)法,表述較簡(jiǎn)潔 function count(start, end) { if (start <= end) { console.log(start++); st = setTimeout(function() { count(start, end); }, 100); } return { cancel: function() { clearTimeout(st); } } } // 這種寫(xiě)法不符合函數(shù)式編程的特點(diǎn),不推薦 function count(start, end) { var timer = null; console.log(start); var obj = { timer: setInterval(function() { if (start <= end) { start++; console.log(start); } else { clearInterval(this.timer); } }, 100), cancel: function() { clearInterval(this.timer); } } return obj; }
題目描述
實(shí)現(xiàn) fizzBuzz 函數(shù),參數(shù) num 與返回值的關(guān)系如下:
1、如果 num 能同時(shí)被 3 和 5 整除,返回字符串 fizzbuzz
2、如果 num 能被 3 整除,返回字符串 fizz
3、如果 num 能被 5 整除,返回字符串 buzz
4、如果參數(shù)為空或者不是 Number 類(lèi)型,返回 false
5、其余情況,返回參數(shù) num
輸入例子:
fizzBuzz(15)
輸出例子:
fizzbuzz
// 一般寫(xiě)法 function fizzBuzz(num) { if (num % 3 === 0 && num % 5 === 0) { /* 特殊地,可換為 if (num % 15 === 0) */ return "fizzbuzz"; } else if (num % 3 === 0) { return "fizz"; } else if (num % 5 === 0) { return "buzz"; } if (num === null || num === "" || typeof num !== "number") { return false; } return num; } // 改進(jìn)寫(xiě)法 function fizzBuzz(num) { if (num === null || num === "" || typeof num !== "number") { return false; } var result = ""; if (num % 3 === 0) { result += "fizz"; } if (num % 5 === 0) { result += "buzz"; } return result ? result : num; }
題目描述
將數(shù)組 arr 中的元素作為調(diào)用函數(shù) fn 的參數(shù)
輸入例子:
argsAsArray(function (greeting, name, punctuation) {return greeting + ", " + name + (punctuation || "!");}, ["Hello", "Ellie", "!"])
輸出例子:
Hello, Ellie!
// 直接法 function argsAsArray(fn, arr) { return fn(arr[0],arr[1],arr[2]); } /* 調(diào)用函數(shù)可以使用call或者apply這兩個(gè)方法,區(qū)別在于call需要將傳給函數(shù)的參數(shù)明確寫(xiě)出來(lái),是 多少參數(shù)就需要寫(xiě)多少參數(shù)。而apply則將傳遞給函數(shù)的參數(shù)放入一個(gè)數(shù)組中,傳入?yún)?shù)數(shù)組即可 */ function argsAsArray(fn, arr) { return fn.apply(this, arr); }
題目描述
將函數(shù) fn 的執(zhí)行上下文改為 obj 對(duì)象
輸入例子:
speak(function () {return this.greeting + ", " + this.name + "!!!";}, {greeting: "Hello", name: "Rebecca"})
輸出例子:
Hello, Rebecca!!!
// apply function speak(fn, obj) { return fn.apply(obj, []); // 第二個(gè)參數(shù)可省略 } // call function speak(fn, obj) { return fn.call(obj); } // bind function speak(fn, obj) { return fn.bind(obj)(); }
題目描述
實(shí)現(xiàn)函數(shù) functionFunction,調(diào)用之后滿(mǎn)足如下條件:
1、返回值為一個(gè)函數(shù) f
2、調(diào)用返回的函數(shù) f,返回值為按照調(diào)用順序的參數(shù)拼接,拼接字符為英文逗號(hào)加一個(gè)空格,即 ", "
3、所有函數(shù)的參數(shù)數(shù)量為 1,且均為 String 類(lèi)型
輸入例子:
functionFunction("Hello")("world")
輸出例子:
Hello, world
// 一般寫(xiě)法 function functionFunction(str) { function f(s) { return str + ", " + s; // 可替換為 return [str, s].join(", "); } return f; } // 精簡(jiǎn)版,省略?xún)?nèi)部命名函數(shù) const functionFunction = str => s => [str, s].join(", ");
題目描述
實(shí)現(xiàn)函數(shù) makeClosures,調(diào)用之后滿(mǎn)足如下條件:
1、返回一個(gè)函數(shù)數(shù)組 result,長(zhǎng)度與 arr 相同
2、運(yùn)行 result 中第 i 個(gè)函數(shù),即 result[i](),結(jié)果與 fn(arr[i]) 相同
輸入例子:
var arr = [1, 2, 3]; var square = function (x) { return x * x; }; var funcs = makeClosures(arr, square); funcs[1]();
輸出例子:
4
// 這種寫(xiě)法比較繞(多層嵌套) function makeClosures(arr, fn) { var result = []; arr.forEach(function(e) { result.push(function(num) { return function() { return fn(num); }; }(e)); }); return result; } // 較簡(jiǎn)潔版(一般按這種方式) function makeClosures(arr, fn) { var result = []; arr.forEach(function(e) { result.push(function() { return fn(e); }); }); return result; } // bind的妙用(推薦寫(xiě)法) function makeClosures(arr, fn) { var result = []; arr.forEach(function(e) { result.push(fn.bind(this, e)); }); return result; } /* 為了更清晰地作對(duì)比,對(duì)這幾種寫(xiě)法分別用箭頭函數(shù)表示 */ // 1 function makeClosures(arr, fn) { let result = []; arr.forEach(e => result.push(num => () => fn(num))(e)); return result; } // 2 function makeClosures(arr, fn) { let result = []; arr.forEach(e => result.push((e => () => fn(e))(e))); return result; } // 3 function makeClosures(arr, fn) { let result = []; arr.forEach(e => result.push(fn.bind(null, e))); return result; }
題目描述
已知函數(shù) fn 執(zhí)行需要 3 個(gè)參數(shù)。請(qǐng)實(shí)現(xiàn)函數(shù) partial,調(diào)用之后滿(mǎn)足如下條件:
1、返回一個(gè)函數(shù) result,該函數(shù)接受一個(gè)參數(shù)
2、執(zhí)行 result(str3) ,返回的結(jié)果與 fn(str1, str2, str3) 一致
輸入例子:
var sayIt = function(greeting, name, punctuation) { return greeting + ", " + name + (punctuation || "!"); }; partial(sayIt, "Hello", "Ellie")("!!!");
輸出例子:
Hello, Ellie!!!
// 一般寫(xiě)法 function partial(fn, str1, str2) { function result(str3) { return fn(str1, str2, str3); } return result; } // call function partial(fn, str1, str2) { function result(str3) { return fn.call(this, str1, str2, str3); } return result; } // apply(這里只是為了對(duì)照) function partial(fn, str1, str2) { function result(str3) { return fn.apply(this, [str1, str2, str3]); } return result; } // 這個(gè)bind會(huì)生成一個(gè)新函數(shù)對(duì)象, 它的str1, str2參數(shù)都定死了, str3未傳入, 一旦傳入就會(huì)執(zhí)行 function partial(fn, str1, str2) { return fn.bind(this, str1, str2); // 或 return fn.bind(null, str1, str2); } // bind同上, 多了一步, 把str3傳入的過(guò)程寫(xiě)在另一個(gè)函數(shù)里面, 而另一個(gè)函數(shù)也有str1, str2參數(shù) function partial(fn, str1, str2) { function result(str3) { return fn.bind(this, str1, str2)(str3); } return result; } // 匿名函數(shù) function partial(fn, str1, str2) { return function(str3) { return fn(str1, str2, str3); } } // ES6 const partial = (fn, str1, str2) => str3 => fn(str1, str2, str3);
題目描述
函數(shù) useArguments 可以接收 1 個(gè)及以上的參數(shù)。請(qǐng)實(shí)現(xiàn)函數(shù) useArguments,返回所有調(diào)用參數(shù)相加后的結(jié)果。本題的測(cè)試參數(shù)全部為 Number 類(lèi)型,不需考慮參數(shù)轉(zhuǎn)換。
輸入例子:
useArguments(1, 2, 3, 4)
輸出例子:
10
// 一般寫(xiě)法,直接利用arguments只有l(wèi)ength屬性的特點(diǎn) function useArguments() { var sum = 0; for (var i = 0; i < arguments.length; ++i) { sum += arguments[i]; } return sum; } // call function useArguments() { var arr = [].slice.call(arguments); // 轉(zhuǎn)成數(shù)組 ([]為Array.prototype的語(yǔ)法糖) return arr.reduce(function(a, b) { return a + b; }); } /* call, bind, apply會(huì)改變生成函數(shù)對(duì)象的this, 使得arguments可以直接使用數(shù)組的方法, 所以也可不轉(zhuǎn)換成數(shù)組而直接使用reduce */ // call同上, 精簡(jiǎn)版 function useArguments() { return [].reduce.call(arguments, function(a, b) { return a + b; }); } // bind function useArguments() { return [].reduce.bind(arguments, function(a, b) { return a + b; })(); } // apply function useArguments() { return [].reduce.apply(arguments, [function(a, b) { return a + b; }]); } // eval的妙用,但不推薦使用eval function useArguments() { var arr = Array.prototype.slice.call(arguments); return eval(arr.join("+")); }
題目描述
實(shí)現(xiàn)函數(shù) callIt,調(diào)用之后滿(mǎn)足如下條件
1、返回的結(jié)果為調(diào)用 fn 之后的結(jié)果
2、fn 的調(diào)用參數(shù)為 callIt 的第一個(gè)參數(shù)之后的全部參數(shù)
輸入例子:
var a = 1; var b = 2; var test = function (first, second) { return first === a && second === b;}; callIt(test, a, b);
輸出例子:
true
// slice function callIt(fn) { var arr = [].slice.call(arguments, 1); /* 將arguments轉(zhuǎn)成數(shù)組并只截取從1開(kāi)始之后的所有元素 */ return fn.apply(this, arr); } // shift function callIt(fn) { return [].shift.call(arguments).apply(null, arguments); /* [].shift.call(arguments)返回了第一個(gè)參數(shù)fn, 因?yàn)檫@里fn等價(jià)于arguments[0] */ } // ES6語(yǔ)法糖 const callIt = (fn, ...args) => fn(...args);
題目描述
實(shí)現(xiàn)函數(shù) partialUsingArguments,調(diào)用之后滿(mǎn)足如下條件:
1、返回一個(gè)函數(shù) result
2、調(diào)用 result 之后,返回的結(jié)果與調(diào)用函數(shù) fn 的結(jié)果一致
3、fn 的調(diào)用參數(shù)為 partialUsingArguments 的第一個(gè)參數(shù)之后的全部參數(shù)以及 result 的調(diào)用參數(shù)
輸入例子:
var a = 1; var b = 2; var c = 3; var d = 4;var test = function (first, second, third, forth) {return first + second + third + forth;};partialUsingArguments(test, a, b)(c, d);
輸出例子:
10
function partialUsingArguments(fn) { var arr = [].slice.call(arguments, 1); /* arr是由partialUsingArguments傳的arguments轉(zhuǎn)換而來(lái) */ function result() { var arrFromResult = [].slice.call(arguments); /* arrFromResult則從函數(shù)result中傳的arguments轉(zhuǎn)換, 所以不能在result外獲取 */ return fn.apply(null, arr.concat(arrFromResult)); } return result; } // 稍微簡(jiǎn)化,跟上面差不多 function partialUsingArguments(fn) { var arr = [].slice.call(arguments, 1); return function() { return fn.apply(this, arr.concat([].slice.call(arguments))); } }
題目描述
已知 fn 為一個(gè)預(yù)定義函數(shù),實(shí)現(xiàn)函數(shù) curryIt,調(diào)用之后滿(mǎn)足如下條件:
1、返回一個(gè)函數(shù) a,a 的 length 屬性值為 1(即顯式聲明 a 接收一個(gè)參數(shù))
2、調(diào)用 a 之后,返回一個(gè)函數(shù) b, b 的 length 屬性值為 1
3、調(diào)用 b 之后,返回一個(gè)函數(shù) c, c 的 length 屬性值為 1
4、調(diào)用 c 之后,返回的結(jié)果與調(diào)用 fn 的返回值一致
5、fn 的參數(shù)依次為函數(shù) a, b, c 的調(diào)用參數(shù)
輸入例子:
var fn = function (a, b, c) {return a + b + c}; curryIt(fn)(1)(2)(3);
輸出例子:
6
// apply function curryIt(fn) { var arr = []; return function(a) { arr.push(a); return function(b) { arr.push(b); return function(c) { arr.push(c); return fn.apply(this, arr); } } } } // 推薦寫(xiě)法 function curryIt(fn) { return function(e1) { return function(e2) { return function(e3) { return fn(e1, e2, e3); // return fn.call(this, e1, e2, e3); 與之等價(jià) } } } } // 箭頭函數(shù) const curryIt = fn => e1 => e2 => e3 => fn(e1, e2, e3);
題目描述
返回參數(shù) a 和 b 的邏輯或運(yùn)算結(jié)果
輸入例子:
or(false, true)
輸出例子:
true
function or(a, b) { return a || b; }
題目描述
返回參數(shù) a 和 b 的邏輯且運(yùn)算結(jié)果
輸入例子:
and(false, true)
輸出例子:
false
function and(a, b) { return a && b; }
題目描述
完成函數(shù) createModule,調(diào)用之后滿(mǎn)足如下要求:
1、返回一個(gè)對(duì)象
2、對(duì)象的 greeting 屬性值等于 str1, name 屬性值等于 str2
3、對(duì)象存在一個(gè) sayIt 方法,該方法返回的字符串為 greeting屬性值 + ", " + name屬性值
// 推薦寫(xiě)法 function createModule(str1, str2) { return { greeting: str1, name: str2, sayIt: function() { return [this.greeting, this.name].join(", "); } } } // Constructor grammer function createModule(str1, str2) { function Obj() { this.greeting = str1; this.name = str2; this.sayIt = function() { return this.greeting + ", " + this.name; } } return new Obj(); }
題目描述
獲取數(shù)字 num 二進(jìn)制形式第 bit 位的值。注意:
1、bit 從 1 開(kāi)始
2、返回 0 或 1
3、舉例:2 的二進(jìn)制為 10,第 1 位為 0,第 2 位為 1
輸入例子:
valueAtBit(128, 8)
輸出例子:
1
// 推薦寫(xiě)法 (時(shí)間復(fù)雜度是O(log bit)) function valueAtBit(num, bit) { return (num & Math.pow(2, bit - 1)) === 0 ? 0 : 1; } // 利用運(yùn)算符特性,簡(jiǎn)潔寫(xiě)法 (時(shí)間復(fù)雜度O(n)) function valueAtBit(num, bit) { return num >> (bit - 1) & 1; } // 轉(zhuǎn)成字符串 (不推薦) function valueAtBit(num, bit) { var s = num.toString(2); var len = s.length; return parseInt(s[len - bit]); }
題目描述
給定二進(jìn)制字符串,將其換算成對(duì)應(yīng)的十進(jìn)制數(shù)字
輸入例子:
base10("11000000")
輸出例子:
192
// parseInt(string, radix) 的可選參數(shù)是操作數(shù)的進(jìn)制說(shuō)明,不是目標(biāo)的進(jìn)制。 function base10(str) { return parseInt(str, 2); }
題目描述
將給定數(shù)字轉(zhuǎn)換成二進(jìn)制字符串。如果字符串長(zhǎng)度不足 8 位,則在前面補(bǔ) 0 到滿(mǎn)8位。
輸入例子:
convertToBinary(65)
輸出例子:
01000001
// 前三種都是采用拼接方法 function convertToBinary(num) { var s = num.toString(2); var len = s.length; if (len < 8) { s = "0000000".slice(0, 8 - len) + s; } return s; } function convertToBinary(num) { var s = num.toString(2); while (s.length < 8) { s = "0" + s; } return s; } function convertToBinary(num) { var s = num.toString(2); return s.length < 8 ? new Array(8 - s.length + 1).join("0").concat(s) : s; } // 推薦寫(xiě)法, 如果長(zhǎng)度過(guò)長(zhǎng), 則截取后8位(倒數(shù)第8位開(kāi)始到最后1位) function convertToBinary(num) { var s = num.toString(2); return s.length < 8 ? ("00000000" + s).slice(-8) : s; }
題目描述
求 a 和 b 相乘的值,a 和 b 可能是小數(shù),需要注意結(jié)果的精度問(wèn)題
輸入例子:
multiply(3, 0.0001)
輸出例子:
0.0003
// 推薦寫(xiě)法 function multiply(a, b) { a = a.toString(); b = b.toString(); var aLen = a.substring(a.indexOf(".") + 1).length; var bLen = b.substring(b.indexOf(".") + 1).length; return (a * b).toFixed(Math.max(aLen, bLen)); /* 本題未說(shuō)明保留小數(shù)位數(shù), 這里假定得出的結(jié)果不含多余的0, 即0.0003000...需轉(zhuǎn)成0.0003 */ }
題目描述
將函數(shù) fn 的執(zhí)行上下文改為 obj,返回 fn 執(zhí)行后的值
輸入例子:
alterContext(function() {return this.greeting + ", " + this.name + "!"; }, {name: "Rebecca", greeting: "Yo" })
輸出例子:
Yo, Rebecca!
/* 將函數(shù)fn的執(zhí)行上下文改為obj對(duì)象, 只需要將obj作為call或apply的第一個(gè)參數(shù)傳入即可 */ // call function alterContext(fn, obj) { return fn.call(obj); // 這里的第二個(gè)參數(shù)可有可無(wú), 如有, 則作為fn的參數(shù)(下同) } // apply function alterContext(fn, obj) { return fn.apply(obj); } // bind function alterContext(fn, obj) { return fn.bind(obj)(); // .bind()返回的是一個(gè)函數(shù), 需要立即執(zhí)行 }
題目描述
給定一個(gè)構(gòu)造函數(shù) constructor,請(qǐng)完成 alterObjects 方法,將 constructor 的所有實(shí)例的 greeting 屬性指向給定的 greeting 變量。
輸入例子:
var C = function(name) {this.name = name; return this;}; var obj1 = new C("Rebecca"); alterObjects(C, "What"s up"); obj1.greeting;
輸出例子:
What"s up
/* 每個(gè)構(gòu)造函數(shù)都有一個(gè)原型對(duì)象,原型對(duì)象都包含一個(gè)指向構(gòu)造函數(shù)的指針,而實(shí)例都包含一個(gè) 指向原型對(duì)象的內(nèi)部指針 */ function alterObjects(constructor, greeting) { constructor.prototype.greeting = greeting; }
題目描述
找出對(duì)象 obj 不在原型鏈上的屬性(注意這題測(cè)試?yán)拥拿疤?hào)后面也有一個(gè)空格~)
1、返回?cái)?shù)組,格式為 key: value
2、結(jié)果數(shù)組不要求順序
輸入例子:
var C = function() {this.foo = "bar"; this.baz = "bim";}; C.prototype.bop = "bip"; iterate(new C());
輸出例子:
["foo: bar", "baz: bim"]
// 前兩種均使用map (推薦寫(xiě)法) function iterate(obj) { return Object.getOwnPropertyNames(obj).map(function(key) { return key + ": " + obj[key]; }); } function iterate(obj) { return Object.keys(obj).map(function(key) { return key + ": " + obj[key]; }); } /*用for-in遍歷可枚舉的屬性, 用hasOwnProperty()方法判斷是否是自有屬性(即不在原型鏈上)*/ function iterate(obj) { var arr = []; for (var key in obj) { if (obj.hasOwnProperty(key)) { arr.push(key + ": " + obj[key]); } } return arr; }以下為正則表達(dá)式相關(guān)題目
可以通過(guò)下面兩種方法創(chuàng)建一個(gè)正則表達(dá)式:
使用一個(gè)正則表達(dá)式字面量,如下所示:
re = /ab+c/;
正則表達(dá)式字面量在腳本加載后編譯。若你的正則表達(dá)式是常量,使用這種方式可以獲得更好的性能。
調(diào)用RegExp對(duì)象的構(gòu)造函數(shù),如下所示:
re = new RegExp("ab+c");
使用構(gòu)造函數(shù),提供了對(duì)正則表達(dá)式運(yùn)行時(shí)的編譯。當(dāng)你知道正則表達(dá)式的模式會(huì)發(fā)生改變, 或者你事先并不了解它的模式或者是從其他地方(比如用戶(hù)的輸入),得到的代碼這時(shí)比較適合用構(gòu)造函數(shù)的方式。
///
題目描述
給定字符串 str,檢查其是否包含數(shù)字,包含返回 true,否則返回 false
輸入例子:
containsNumber("abc123")
輸出例子:
true
d 匹配一個(gè)數(shù)字, 等價(jià)于[0-9]。 例如, /d/ 或者 /[0-9]/ 匹配 "B2 is the suite number." 中的"2"。 test()方法執(zhí)行一個(gè)檢索,用來(lái)查看正則表達(dá)式與指定的字符串是否匹配。返回true或false。
function containsNumber(str) { return /d/.test(str); }
題目描述
給定字符串 str,檢查其是否包含連續(xù)重復(fù)的字母(a-zA-Z),包含返回 true,否則返回 false
輸入例子:
containsRepeatingLetter("rattler")
輸出例子:
true
[xyz] 一個(gè)字符集合, 匹配方括號(hào)的中任意字符。可以使用破折號(hào)(-)來(lái)指定一個(gè)字符范圍。 對(duì)于點(diǎn)(.)和星號(hào)(*)這樣的特殊符號(hào)在一個(gè)字符集中沒(méi)有特殊的意義。他們不必進(jìn)行轉(zhuǎn)義,不過(guò)轉(zhuǎn)義也是起作用的。 例如,[abcd] 和[a-d]是一樣的。他們都匹配"brisket"中的‘b’,也都匹配“city”中的‘c’。 /[a-z.]+/ 和/[w.]+/都匹配“test.i.ng”中的所有字符。 (x) 匹配 "x" 并且記住匹配項(xiàng),就像下面的例子展示的那樣。括號(hào)被稱(chēng)為"捕獲括號(hào)"。 模式/(foo) (bar) 1 2/中的"(foo)"和"(bar)"匹配并記住字符串"foo bar foo bar"中前兩個(gè)單詞。 模式中的 1 和 2 匹配字符串的后兩個(gè)單詞。注意 1、2、 是用在正則表達(dá)式的匹配環(huán)節(jié)。 在正則表達(dá)式的替換環(huán)節(jié),則要使用像 $1、$2、$n 這樣的語(yǔ)法,例如, "bar foo".replace( /(...) (...)/, "$2 $1" )。
function containsRepeatingLetter(str) { return /([a-zA-Z])1/.test(str); }
題目描述
給定字符串 str,檢查其是否以元音字母結(jié)尾
1、元音字母包括 a,e,i,o,u,以及對(duì)應(yīng)的大寫(xiě)
2、包含返回 true,否則返回 false
輸入例子:
endsWithVowel("gorilla")
輸出例子:
true
$ 匹配輸入的結(jié)束。如果多行標(biāo)示被設(shè)置為true,那么也匹配換行符前的位置。 例如,/t$/ 并不會(huì)匹配 "eater" 中的 "t",但是會(huì)匹配 "eat" 中的 "t"。 通過(guò)標(biāo)志進(jìn)行高級(jí)搜索 正則表達(dá)式有四個(gè)可選參數(shù)進(jìn)行全局和不分大小寫(xiě)搜索。 這些參數(shù)既可以多帶帶使用也可以一起使用在任何順序和包含正則表達(dá)式的部分中。 正則表達(dá)式標(biāo)志 標(biāo)志 描述 g 全局搜索。 i 不區(qū)分大小寫(xiě)搜索。 m 多行搜索。 y 執(zhí)行“粘性”搜索,匹配從目標(biāo)字符串的當(dāng)前位置開(kāi)始,可以使用y標(biāo)志。
function endsWithVowel(str) { return /[aeiou]$/i.test(str); }
題目描述
給定字符串 str,檢查其是否包含連續(xù)3個(gè)數(shù)字
1、如果包含,返回最新出現(xiàn)的3個(gè)數(shù)字的字符串
2、如果不包含,返回 false
輸入例子:
captureThreeNumbers("9876543")
輸出例子:
987
function captureThreeNumbers(str) { var arr = str.match(/d{3}/); // 尋找三個(gè)數(shù)字字符 d{3} return arr ? arr[0] : false; }
題目描述
給定字符串 str,檢查其是否符合如下格式
1、XXX-XXX-XXXX
2、其中 X 為 Number 類(lèi)型
輸入例子:
matchesPattern("800-555-1212")
輸出例子:
true
^ 匹配輸入的開(kāi)始。如果多行標(biāo)志被設(shè)置為true,那么也匹配換行符后緊跟的位置。 例如,/^A/ 并不會(huì)匹配 "an A" 中的 "A",但是會(huì)匹配 "An E" 中的 "A"。 當(dāng) "^" 作為第一個(gè)字符出現(xiàn)在一個(gè)字符集合模式時(shí),它將會(huì)有不同的含義。
function matchesPattern(str) { return /^(d{3}-){2}d{4}$/.test(str); }
題目描述
給定字符串 str,檢查其是否符合美元書(shū)寫(xiě)格式
1、以 $ 開(kāi)始
2、整數(shù)部分,從個(gè)位起,滿(mǎn) 3 個(gè)數(shù)字用 , 分隔
3、如果為小數(shù),則小數(shù)部分長(zhǎng)度為 2
4、正確的格式如:$1,023,032.03 或者 $2.03,錯(cuò)誤的格式如:$3,432,12.12 或者 $34,344.3
輸入例子:
isUSD("$20,933,209.93")
輸出例子:
true
? 匹配前面一個(gè)表達(dá)式0次或者1次。等價(jià)于 {0,1}。 例如,/e?le?/ 匹配 "angel" 中的 "el",和 "angle" 中的 "le" (注意第二個(gè) ? 前面的匹配表達(dá)式是 e 而不是 le) 以及 "oslo" 中的"l"。 如果緊跟在任何量詞 *、 +、? 或 {} 的后面,將會(huì)使量詞變?yōu)榉秦澙返模ㄆヅ浔M量少的字符),和缺省 使用的貪婪模式(匹配盡可能多的字符)正好相反。 例如,對(duì) "123abc" 應(yīng)用 /d+/ 將會(huì)返回 "123",如果使用 /d+?/,那么就只會(huì)匹配到 "1"。 還可以運(yùn)用于向前斷言 正向肯定查找x(?=y) 和 正向否定查找x(?!y) 。 * 匹配前一個(gè)表達(dá)式0次或多次。等價(jià)于 {0,}。 例如,/bo*/會(huì)匹配 "A ghost boooooed" 中的 "booooo" 和 "A bird warbled" 中的 "b", 但是在 "A goat grunted" 中將不會(huì)匹配任何東西。 . (小數(shù)點(diǎn))匹配 除了換行符( )之外的任何單個(gè)字符。 例如, /.n/將會(huì)匹配"nay, an apple is on the tree"中的"an"和"on", 但是不會(huì)匹配 "nay"。
function isUSD(str) { return /^$d{1,3}(,d{3})*(.d{2})?$/.test(str); }
如有錯(cuò)誤,懇請(qǐng)指正,也歡迎各位大佬貢獻(xiàn)出更好的解法
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/81901.html
摘要:前言今天和大家一起聊聊的推薦書(shū)籍,每一本都是精選,做前端開(kāi)發(fā)的朋友們?nèi)绻麤](méi)讀過(guò),可以嘗試一下。如果怕麻煩,也可以關(guān)注曉舟報(bào)告,發(fā)送獲取書(shū)籍,四個(gè)字,就可以得到電子書(shū)的提取碼。 前言 今天和大家一起聊聊JavaScript的推薦書(shū)籍,每一本都是精選,做前端開(kāi)發(fā)的朋友們?nèi)绻麤](méi)讀過(guò),可以嘗試一下。下面給大家簡(jiǎn)單介紹了書(shū)的內(nèi)容,還有讀書(shū)的方法,希望可以幫大家提升讀書(shū)效率。 一、《JavaScr...
摘要:一基礎(chǔ)接口的意義百度規(guī)范擴(kuò)展回調(diào)抽象類(lèi)的意義想不想通過(guò)一線(xiàn)互聯(lián)網(wǎng)公司面試文檔整理為電子書(shū)掘金簡(jiǎn)介谷歌求職記我花了八個(gè)月準(zhǔn)備谷歌面試掘金原文鏈接翻譯者 【面試寶典】從對(duì)象深入分析 Java 中實(shí)例變量和類(lèi)變量的區(qū)別 - 掘金原創(chuàng)文章,轉(zhuǎn)載請(qǐng)務(wù)必保留原出處為:http://www.54tianzhisheng.cn/... , 歡迎訪(fǎng)問(wèn)我的站點(diǎn),閱讀更多有深度的文章。 實(shí)例變量 和 類(lèi)變量...
摘要:前言上一期說(shuō)好的的核心模塊進(jìn)階以及基本應(yīng)用的使用將在號(hào)或者號(hào)與大家見(jiàn)面在此之前我想跟大家分享幾個(gè)前端經(jīng)典的面試題為什么我突然想寫(xiě)這么一篇文章呢今天我應(yīng)公司要求去面試了下幾位招聘者然后又現(xiàn)場(chǎng)整不出幾個(gè)難題就搜了一下前端變態(tài)面試題,前提我并不是 前言 上一期說(shuō)好的node.js的核心模塊進(jìn)階以及基本web應(yīng)用的使用將在2號(hào)或者3號(hào)與大家見(jiàn)面,在此之前我想跟大家分享幾個(gè)前端經(jīng)典的面試題,為什...
摘要:前言上一期說(shuō)好的的核心模塊進(jìn)階以及基本應(yīng)用的使用將在號(hào)或者號(hào)與大家見(jiàn)面在此之前我想跟大家分享幾個(gè)前端經(jīng)典的面試題為什么我突然想寫(xiě)這么一篇文章呢今天我應(yīng)公司要求去面試了下幾位招聘者然后又現(xiàn)場(chǎng)整不出幾個(gè)難題就搜了一下前端變態(tài)面試題,前提我并不是 前言 上一期說(shuō)好的node.js的核心模塊進(jìn)階以及基本web應(yīng)用的使用將在2號(hào)或者3號(hào)與大家見(jiàn)面,在此之前我想跟大家分享幾個(gè)前端經(jīng)典的面試題,為什...
閱讀 2001·2019-08-29 16:27
閱讀 1370·2019-08-29 16:14
閱讀 3372·2019-08-29 14:18
閱讀 3455·2019-08-29 13:56
閱讀 1252·2019-08-29 11:13
閱讀 2118·2019-08-28 18:19
閱讀 3439·2019-08-27 10:57
閱讀 2273·2019-08-26 11:39