一、数组
1. 查找数组元素位置
function indexOf(arr, item) {
if (Array.prototype.indexOf){
return arr.indexOf(item);
} else {
for (var i = 0; i < arr.length; i++){
if (arr[i] === item){
return i;
}
}
}
return -1;
}
2.数组求和
function(arr) {
return arr.reduce(function(prev, curr, index, arr) {
return prev + curr;
});
};
function sum(arr) {
return eval(arr.join('+'));
}
3.移除数组中的元素
移除数组 arr 中的所有值与 item 相等的元素。不要直接修改数组 arr,结果返回新的数组
不改变原数组:
function remove(arr, item) {
return arr.filter(function(x) {
return x !== item;
});
}
改变原数组:
function removeWithoutCopy(arr, item){
for(i=arr.length-1;i>=0;i--){
if(arr[i]==item){
arr.splice(i,1);
}
}
return arr;
}
4. 添加元素 item(concat不会改变原数组)(堆方法pop/push和栈方法shift/unshift都会改变原数组)
在开头
function prepend(arr, item) {
//将arr数组复制给a
var a = arr.slice(0);
//使用unshift方法向a开头添加item
a.unshift(item);
return a;
}
function prepend(arr, item) {
var arr1=[item];
return arr1.concat(arr)
}
在结尾
function(arr, item) {
var newArr = arr.slice(0); // slice(start, end)浅拷贝数组
newArr.push(item);
return newArr;
};
function append(arr, item) {
return arr.concat(item)
}
4.删除数组最后一个元素
function truncate(arr) {
var a = arr.slice(0);
a.pop();
return a;
}
function truncate(arr) {
return arr.slice(0,arr.length-1);
}
5.删除数组第一个元素
function curtail(arr) {
return arr.slice(1);
}
function curtail(arr) {
//复制数组arr
var a = arr.slice(0);
a.shift();
return a;
}
function curtail(arr) {
return arr.filter(function(x,index){
return index != 0;
});
}
6. 数组合并
合并数组 arr1 和数组 arr2。不要直接修改数组 arr,结果返回新的数组
function concat(arr1, arr2) {
return arr1.concat(arr2);
}
7. 添加元素
在数组 arr 的 index 处添加元素 item。不要直接修改数组 arr,结果返回新的数组
function insert(arr, item, index) {
var a = arr.slice(0);
a.splice(index,0,item);
return a;
}
8. 计数
统计数组 arr 中值等于 item 的元素出现的次数
function count(arr, item) {
var count = 0;
arr.forEach(function(e){
//e为arr中的每一个元素,与item相等则count+1
e == item ? count++ : 0;
});
return count;
}
function count(arr, item) {
return arr.filter(function(a){
return (a == item);
}).length
}
9.查找重复元素
找出数组 arr 中重复出现过的元素
function duplicates(arr) {
var result = [];
arr.forEach(function(item){
if(arr.indexOf(item) != arr.lastIndexOf(item) && result.indexOf(item) == -1){
result.push(item)
}
});
return result;
}
function duplicates(arr) {
//声明两个数组,a数组用来存放结果,b数组用来存放arr中每个元素的个数
var a = [],b = [];
//遍历arr,如果以arr中元素为下标的的b元素已存在,则该b元素加1,否则设置为1
for(var i = 0; i < arr.length; i++){
if(!b[arr[i]]){
b[arr[i]] = 1;
continue;
}
b[arr[i]]++;
}
//遍历b数组,将其中元素值大于1的元素下标存入a数组中
for(var i = 0; i < b.length; i++){
if(b[i] > 1){
a.push(i);
}
}
return a;
}
10. 求二次方
为数组 arr 中的每个元素求二次方。不要直接修改数组 arr,结果返回新的数组
function square(arr) {
return arr.map(function(item){
return item * item;
})
}
11.查找元素位置
在数组 arr 中,查找值与 item 相等的元素出现的所有位置
function findAllOccurrences(arr, target) {
var array= [];
var index = arr.indexOf(target);
while(index != -1){
array.push(index);
index = arr.indexOf(target,index+1);
}
return array;
}
function findAllOccurrences(arr, target) {
var a = [];
for(var i = 0; i < arr.length; i++){
if(target == arr[i])
a.push(i);
}
return a;
}
二、函数
1.函数传参
将数组 arr 中的元素作为调用函数 fn 的参数
function argsAsArray(fn, arr) {
return fn.apply(null,arr)
}
2. 函数的上下文
将函数 fn 的执行上下文改为 obj 对象
function speak(fn, obj) {
return fn.call(obj)
}
3. 返回函数
实现函数 functionFunction,调用之后满足如下条件:
1、返回值为一个函数 f
2、调用返回的函数 f,返回值为按照调用顺序的参数拼接,拼接字符为英文逗号加一个空格,即 ', '
3、所有函数的参数数量为 1,且均为 String 类型
function functionFunction(str) {
var f = function(s){
return str+", "+s;
}
return f;
}
4. 使用闭包
实现函数 makeClosures,调用之后满足如下条件:
1、返回一个函数数组 result,长度与 arr 相同
2、运行 result 中第 i 个函数,即 result[i](),结果与 fn(arr[i]) 相同
function makeClosures(arr, fn) {
var result = [];
arr.forEach(function(e){
result.push(function(num){
return fn(num);
}(e));
});
return result;
}
5.二次封装函数
已知函数 fn 执行需要 3 个参数。请实现函数 partial,调用之后满足如下条件:
1、返回一个函数 result,该函数接受一个参数
2、执行 result(str3) ,返回的结果与 fn(str1, str2, str3) 一致
function partial(fn, str1, str2) {
var result = function(str3){
return fn.call(this, str1, str2, str3);
}
return result;
}
6. 使用 arguments
函数 useArguments 可以接收 1 个及以上的参数。
请实现函数 useArguments,返回所有调用参数相加后的结果。本题的测试参数全部为 Number 类型,不需考虑参数转换。
function useArguments() {
var arr=Array.prototype.slice.call(arguments)//把arguments类数组转化为数组
return eval(arr.join("+"));//求和
}
function useArguments() {
var args = Array.prototype.slice.call(arguments);
return args.reduce(function(per,cur){
return per + cur
})
}
7. 使用 apply 调用函数
实现函数 callIt,调用之后满足如下条件
1、返回的结果为调用 fn 之后的结果
2、fn 的调用参数为 callIt 的第一个参数之后的全部参数
function callIt(fn) {
//将arguments转化为数组后,截取第一个元素之后的所有元素
var args=Array.prototype.slice.call(arguments,1);
var result=fn.apply(null,args);
return result;
}
function callIt(fn) {
return fn.apply(this,[].slice.call(arguments,1));
}
8. 二次封装函数
实现函数 partialUsingArguments,调用之后满足如下条件:
1、返回一个函数 result
2、调用 result 之后,返回的结果与调用函数 fn 的结果一致
3、fn 的调用参数为 partialUsingArguments 的第一个参数之后的全部参数以及 result 的调用参数
function partialUsingArguments(fn) {
//先获取p函数第一个参数之后的全部参数
var args = Array.prototype.slice.call(arguments,1);
//声明result函数
var result = function(){
//使用concat合并两个或多个数组中的元素
return fn.apply(null, args.concat([].slice.call(arguments)));
}
return result;
}
9. 柯里化
已知 fn 为一个预定义函数,实现函数 curryIt,调用之后满足如下条件:
1、返回一个函数 a,a 的 length 属性值为 1(即显式声明 a 接收一个参数)
2、调用 a 之后,返回一个函数 b, b 的 length 属性值为 1
3、调用 b 之后,返回一个函数 c, c 的 length 属性值为 1
4、调用 c 之后,返回的结果与调用 fn 的返回值一致
5、fn 的参数依次为函数 a, b, c 的调用参数
function curryIt(fn) {
//获取fn参数的数量
var n = fn.length;
//声明一个数组args
var args = [];
//返回一个匿名函数
return function(arg){
//将curryIt后面括号中的参数放入数组
args.push(arg);
//如果args中的参数个数小于fn函数的参数个数,
//则执行arguments.callee(其作用是引用当前正在执行的函数,这里是返回的当前匿名函数)。
//否则,返回fn的调用结果
if(args.length < n){
return arguments.callee;
}else return fn.apply("",args);
}
}
function curryIt(fn) {
return function a(xa){
return function b(xb){
return function c(xc){
return fn.call(this,xa,xb,xc);
};
};
};
}
function curryIt(fn) {
function curry1(a){
function curry2(b){
function curry3(c){
return fn(a,b,c);
}
return curry3;
}
return curry2;
}
return curry1;
}
三、