javascript
JS能力测评经典题
每道題都寫多種解法,開闊思路。一共45道題。
因?yàn)榕?途W(wǎng)oj不支持ES6語法,所以大多數(shù)寫法只給出傳統(tǒng)寫法。
題目描述
找出元素 item 在給定數(shù)組 arr 中的位置
輸出描述:
如果數(shù)組中存在 item,則返回元素在數(shù)組中的位置,否則返回 -1
輸入例子:
indexOf([ 1, 2, 3, 4 ], 3)
輸出例子:
2
題目描述
計(jì)算給定數(shù)組 arr 中所有元素的總和
輸入描述:
數(shù)組中的元素均為 Number 類型
輸入例子:
sum([ 1, 2, 3, 4 ])
輸出例子:
10
題目描述
移除數(shù)組 arr 中的所有值與 item 相等的元素。不要直接修改數(shù)組 arr,結(jié)果返回新的數(shù)組
輸入例子:
remove([1, 2, 3, 4, 2], 2)
輸出例子:
[1, 3, 4]
移除數(shù)組 arr 中的所有值與 item 相等的元素,直接在給定的 arr 數(shù)組上進(jìn)行操作,并將結(jié)果返回
輸入例子:
removeWithoutCopy([1, 2, 2, 3, 4, 2, 2], 2)
輸出例子:
[1, 3, 4]
題目描述
在數(shù)組 arr 末尾添加元素 item。不要直接修改數(shù)組 arr,結(jié)果返回新的數(shù)組
輸入例子:
append([1, 2, 3, 4], 10)
輸出例子:
[1, 2, 3, 4, 10]
題目描述
刪除數(shù)組 arr 最后一個(gè)元素。不要直接修改數(shù)組 arr,結(jié)果返回新的數(shù)組
輸入例子:
truncate([1, 2, 3, 4])
輸出例子:
[1, 2, 3]
題目描述
在數(shù)組 arr 開頭添加元素 item。不要直接修改數(shù)組 arr,結(jié)果返回新的數(shù)組
輸入例子:
prepend([1, 2, 3, 4], 10)
輸出例子:
[10, 1, 2, 3, 4]
題目描述
刪除數(shù)組 arr 第一個(gè)元素。不要直接修改數(shù)組 arr,結(jié)果返回新的數(shù)組
輸入例子:
curtail([1, 2, 3, 4])
輸出例子:
[2, 3, 4]
題目描述
合并數(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]
題目描述
在數(shù)組 arr 的 index 處添加元素 item。不要直接修改數(shù)組 arr,結(jié)果返回新的數(shù)組
輸入例子:
insert([1, 2, 3, 4], 'z', 2)
輸出例子:
[1, 2, 'z', 3, 4]
題目描述
統(tǒng)計(jì)數(shù)組 arr 中值等于 item 的元素出現(xiàn)的次數(shù)
輸入例子:
count([1, 2, 4, 4, 3, 4, 3], 4)
輸出例子:
3
題目描述
找出數(shù)組 arr 中重復(fù)出現(xiàn)過的元素
輸入例子:
duplicates([1, 2, 4, 4, 3, 3, 1, 5, 3]).sort()
輸出例子:
[1, 3, 4]
關(guān)于indexOf與lastIndexOf的文檔
// 一般寫法,排序之后判斷相鄰元素是否相等 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]
題目描述
在數(shù)組 arr 中,查找值與 item 相等的元素出現(xiàn)的所有位置
輸入例子:
findAllOccurrences('abcdefabc'.split(''), 'a').sort()
輸出例子:
[0, 6]
題目描述
給定的 js 代碼中存在全局變量,請修復(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; }// 把對象歸屬改為原型 function globals() {globals.prototype.myObject = {name : 'Jory'};return globals; }// 把對象改為匿名的 function globals() {return { name : 'Jory' }; }題目描述
請修復(fù)給定的 js 代碼中,函數(shù)定義存在的問題
function functions(flag) {if (flag) {function getValue() { return 'a'; }} else {function getValue() { return 'b'; }}return getValue(); }輸入例子:
functions(true)
輸出例子:
a
題目描述
修改 js 代碼中 parseInt 的調(diào)用方式,使之通過全部測試用例
function parse2Int(num) {return parseInt(num); }輸入例子:
parse2Int('12'); parse2Int('12px'); parse2Int('0x12')
輸出例子:
12; 12; 0
題目描述
判斷 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、返回的對象中需要包含一個(gè) cancel 方法,用于停止定時(shí)操作
3、第一個(gè)數(shù)需要立即輸出
setInterval setTimeout clearInterval() clearTimeout()
// 一般寫法,使用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,遞歸寫法,表述較簡潔 function count(start, end) {if (start <= end) {console.log(start++);st = setTimeout(function() {count(start, end);}, 100);}return {cancel: function() {clearTimeout(st);}} }// 這種寫法不符合函數(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 類型,返回 false
5、其余情況,返回參數(shù) num
輸入例子:
fizzBuzz(15)
輸出例子:
fizzbuzz
題目描述
將數(shù)組 arr 中的元素作為調(diào)用函數(shù) fn 的參數(shù)
輸入例子:
argsAsArray(function (greeting, name, punctuation) {return greeting + ', ' + name + (punctuation || '!');}, ['Hello', 'Ellie', '!'])
輸出例子:
Hello, Ellie!
題目描述
將函數(shù) fn 的執(zhí)行上下文改為 obj 對象
輸入例子:
speak(function () {return this.greeting + ', ' + this.name + '!!!';}, {greeting: 'Hello', name: 'Rebecca'})
輸出例子:
Hello, Rebecca!!!
題目描述
實(shí)現(xiàn)函數(shù) functionFunction,調(diào)用之后滿足如下條件:
1、返回值為一個(gè)函數(shù) f
2、調(diào)用返回的函數(shù) f,返回值為按照調(diào)用順序的參數(shù)拼接,拼接字符為英文逗號加一個(gè)空格,即 ', '
3、所有函數(shù)的參數(shù)數(shù)量為 1,且均為 String 類型
輸入例子:
functionFunction('Hello')('world')
輸出例子:
Hello, world
題目描述
實(shí)現(xiàn)函數(shù) makeClosures,調(diào)用之后滿足如下條件:
1、返回一個(gè)函數(shù)數(shù)組 result,長度與 arr 相同
2、運(yùn)行 result 中第 i 個(gè)函數(shù),即 result[i](),結(jié)果與 fn(arr[i]) 相同
輸入例子:
輸出例子:
4
理解閉包
// 這種寫法比較繞(多層嵌套) function makeClosures(arr, fn) {var result = [];arr.forEach(function(e) {result.push(function(num) {return function() {return fn(num);};}(e));});return result; }// 較簡潔版(一般按這種方式) function makeClosures(arr, fn) {var result = [];arr.forEach(function(e) {result.push(function() {return fn(e);});});return result; }// bind的妙用(推薦寫法) function makeClosures(arr, fn) {var result = [];arr.forEach(function(e) {result.push(fn.bind(this, e));});return result; }/* 為了更清晰地作對比,對這幾種寫法分別用箭頭函數(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ù)。請實(shí)現(xiàn)函數(shù) partial,調(diào)用之后滿足如下條件:
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!!!
關(guān)于js中 call、apply、bind 的用法可參考這篇博客
// 一般寫法 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(這里只是為了對照) function partial(fn, str1, str2) {function result(str3) {return fn.apply(this, [str1, str2, str3]);}return result; }// 這個(gè)bind會生成一個(gè)新函數(shù)對象, 它的str1, str2參數(shù)都定死了, str3未傳入, 一旦傳入就會執(zhí)行 function partial(fn, str1, str2) {return fn.bind(this, str1, str2); // 或 return fn.bind(null, str1, str2); }// bind同上, 多了一步, 把str3傳入的過程寫在另一個(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ù)。請實(shí)現(xiàn)函數(shù) useArguments,返回所有調(diào)用參數(shù)相加后的結(jié)果。本題的測試參數(shù)全部為 Number 類型,不需考慮參數(shù)轉(zhuǎn)換。
輸入例子:
useArguments(1, 2, 3, 4)
輸出例子:
10
關(guān)于arguments的介紹
// 一般寫法,直接利用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的語法糖)return arr.reduce(function(a, b) {return a + b;}); } /* call, bind, apply會改變生成函數(shù)對象的this, 使得arguments可以直接使用數(shù)組的方法,所以也可不轉(zhuǎn)換成數(shù)組而直接使用reduce */// call同上, 精簡版 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)用之后滿足如下條件
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
箭頭函數(shù)的arguments 剩余參數(shù)(rest parameter)
// slice function callIt(fn) {var arr = [].slice.call(arguments, 1); /* 將arguments轉(zhuǎn)成數(shù)組并只截取從1開始之后的所有元素 */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語法糖 const callIt = (fn, ...args) => fn(...args);題目描述
實(shí)現(xiàn)函數(shù) partialUsingArguments,調(diào)用之后滿足如下條件:
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
題目描述
已知 fn 為一個(gè)預(yù)定義函數(shù),實(shí)現(xiàn)函數(shù) curryIt,調(diào)用之后滿足如下條件:
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
JS中的柯里化(currying)
// 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);}}} }// 推薦寫法 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
題目描述
返回參數(shù) a 和 b 的邏輯且運(yùn)算結(jié)果
輸入例子:
and(false, true)
輸出例子:
false
題目描述
完成函數(shù) createModule,調(diào)用之后滿足如下要求:
1、返回一個(gè)對象
2、對象的 greeting 屬性值等于 str1, name 屬性值等于 str2
3、對象存在一個(gè) sayIt 方法,該方法返回的字符串為 greeting屬性值 + ', ' + name屬性值
題目描述
獲取數(shù)字 num 二進(jìn)制形式第 bit 位的值。注意:
1、bit 從 1 開始
2、返回 0 或 1
3、舉例:2 的二進(jìn)制為 10,第 1 位為 0,第 2 位為 1
輸入例子:
valueAtBit(128, 8)
輸出例子:
1
題目描述
給定二進(jìn)制字符串,將其換算成對應(yīng)的十進(jìn)制數(shù)字
輸入例子:
base10('11000000')
輸出例子:
192
題目描述
將給定數(shù)字轉(zhuǎn)換成二進(jìn)制字符串。如果字符串長度不足 8 位,則在前面補(bǔ) 0 到滿8位。
輸入例子:
convertToBinary(65)
輸出例子:
01000001
題目描述
求 a 和 b 相乘的值,a 和 b 可能是小數(shù),需要注意結(jié)果的精度問題
輸入例子:
multiply(3, 0.0001)
輸出例子:
0.0003
String.prototype.substring()
Number.prototype.toFixed()
// 推薦寫法 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));/* 本題未說明保留小數(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!
題目描述
給定一個(gè)構(gòu)造函數(shù) constructor,請完成 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
繼承與原型鏈(prototype chain)
/* 每個(gè)構(gòu)造函數(shù)都有一個(gè)原型對象,原型對象都包含一個(gè)指向構(gòu)造函數(shù)的指針,而實(shí)例都包含一個(gè)指向原型對象的內(nèi)部指針 */function alterObjects(constructor, greeting) {constructor.prototype.greeting = greeting; }題目描述
找出對象 obj 不在原型鏈上的屬性(注意這題測試?yán)拥拿疤柡竺嬉灿幸粋€(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"]
Object.getOwnPropertyNames()
Object.keys()
Object.prototype.hasOwnProperty()
// 前兩種均使用map (推薦寫法) 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)題目
可以通過下面兩種方法創(chuàng)建一個(gè)正則表達(dá)式:
使用一個(gè)正則表達(dá)式字面量,如下所示:
re = /ab+c/;
正則表達(dá)式字面量在腳本加載后編譯。若你的正則表達(dá)式是常量,使用這種方式可以獲得更好的性能。
調(diào)用RegExp對象的構(gòu)造函數(shù),如下所示:
re = new RegExp("ab+c");
使用構(gòu)造函數(shù),提供了對正則表達(dá)式運(yùn)行時(shí)的編譯。當(dāng)你知道正則表達(dá)式的模式會發(fā)生改變, 或者你事先并不了解它的模式或者是從其他地方(比如用戶的輸入),得到的代碼這時(shí)比較適合用構(gòu)造函數(shù)的方式。
///題目描述
給定字符串 str,檢查其是否包含數(shù)字,包含返回 true,否則返回 false
輸入例子:
containsNumber('abc123')
輸出例子:
true
題目描述
給定字符串 str,檢查其是否包含連續(xù)重復(fù)的字母(a-zA-Z),包含返回 true,否則返回 false
輸入例子:
containsRepeatingLetter('rattler')
輸出例子:
true
題目描述
給定字符串 str,檢查其是否以元音字母結(jié)尾
1、元音字母包括 a,e,i,o,u,以及對應(yīng)的大寫
2、包含返回 true,否則返回 false
輸入例子:
endsWithVowel('gorilla')
輸出例子:
true
題目描述
給定字符串 str,檢查其是否包含連續(xù)3個(gè)數(shù)字
1、如果包含,返回最新出現(xiàn)的3個(gè)數(shù)字的字符串
2、如果不包含,返回 false
輸入例子:
captureThreeNumbers('9876543')
輸出例子:
987
String.prototype.match()
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 類型
輸入例子:
matchesPattern('800-555-1212')
輸出例子:
true
題目描述
給定字符串 str,檢查其是否符合美元書寫格式
1、以 $ 開始
2、整數(shù)部分,從個(gè)位起,滿 3 個(gè)數(shù)字用 , 分隔
3、如果為小數(shù),則小數(shù)部分長度為 2
4、正確的格式如:$1,023,032.03 或者 $2.03,錯(cuò)誤的格式如:$3,432,12.12 或者 $34,344.3
輸入例子:
isUSD('$20,933,209.93')
輸出例子:
true
如有錯(cuò)誤,懇請指正,也歡迎各位大佬貢獻(xiàn)出更好的解法
總結(jié)
- 上一篇: 订单可视化(智能制造、流程再造、企业信息
- 下一篇: 运维利器1-supervisor