javascript的有趣逻辑片段

准备面试的刷题过程中,遇到了一些题,比较有意思,轻巧。
加强运用一下js原生语法,多解。

题目来源:https://github.com/rmurphey/j...
A test-driven approach to assessing JS skills

  • 统计数组 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
}

function count(arr, item) {
    var res;
    return (res = arr.toString().match(new RegExp("\\b"+item+"\\b","g")))?res.length:0;
}

function count(arr, item) {
            var count = 0;
            arr.map(function(a) {
                if(a === item) {
                    count++;
                }
            });
            return count;
        }
        
  • 为数组 arr 中的每个元素求二次方。不要直接修改数组 arr,结果返回新的数组

function square(arr) {
    return arr.map(function(item,index,array){
        return item*item;
    })
}

function square(arr) {
   //声明一个新的数组存放结果
     var a = [];
     arr.forEach(function(e){
         //将arr中的每一个元素求平方后,加入到a数组中
         a.push(e*e);
     });
     return a;
 }

function square(arr) {
//复制一个arr数组
    var newarr = arr.slice(0);
    for (var i=0;i<newarr.length;i++){
        newarr[i]= newarr[i]* newarr[i];
    }
    return newarr;
}

function square(arr) {
    return arr.map(function(item){
        return Math.pow(item, 2);
    })
}
  • 将数组 arr 中的元素作为调用函数 fn 的参数

function argsAsArray(fn, arr) {
  return fn.apply(this, arr);
 }

function argsAsArray(fn, arr) {
    return function(para1,para2){ 
        return  para1.apply(this,para2);
    }(fn,arr);
}
  • 完成函数 createModule,调用之后满足如下要求:

1、返回一个对象
2、对象的 greeting 属性值等于 str1,name 属性值等于 str2
3、对象存在一个 sayIt 方法,该方法返回的字符串为 greeting属性值 + ', ' +name属性值

function createModule(str1, str2) {
     var obj = {
         greeting : str1,
         name     : str2,
         sayIt    : function(){
             //两个属性前面都需要加上this
             return this.greeting+", "+this.name;
         }
     };
     return obj;
 }

//使用构造函数法
function createModule(str1, str2) {
    function Obj(){
        this.greeting = str1;
        this.name = str2;
        this.sayIt = function(){
            return this.greeting + ', ' + this.name;
        };
    }
    return new Obj();
}

//构造函数与原型组合
function createModule(str1, str2) {
    function CreateMod(){
        this.greeting = str1;
        this.name = str2;
    }
    CreateMod.prototype.sayIt = function(){
        return this.greeting + ', '  + this.name;
    }
    return new CreateMod();
}

  • 已知 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 的调用参数

输入例子:

var fn = function (a, b, c) {return a + b + c}; curryIt(fn)(1)(2)(3);
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 indexof(arr,item){
    for(var i = 0,len = arr.length;i<len;i++){
        var ite = arr[i];
        if(ite == item){
            console.log(ite == item);
            return i;
        }else{
            return -1;
        }
    }
}

function indexof(arr,item){
    return arr.indexOf(item);
}

  • 数组求和

function sum(arr) {
    return eval(arr.join("+"));
};
  • 删除给定元素

   function remove(arr, item) {
        for(var i=0, m=arr.length, res=[]; i<m; i++){
            if(item === arr[i]) continue;
            else res.push(arr[i]);
        }
        return res;
    }

function remove(arr, item) {
    var newA=arr.slice(0);
    for(var i=newA.indexOf(item);i>-1;i=newA.indexOf(item)){
        newA.splice(i,1);
    }
    return newA;
}
  • 将函数放入数组,参数放入函数,调用数组里面的函数,返回函数执行的结果。

function makeclosures(arr,fn){
    var funcs = [];
    for(var i = 0;i<arr.length;++i){
        (function(v){
            funcs[v] = function(){
                return fn.call(null,arr[v])
            }
        })(i)
    }
}


  • 将函数a暂时保存在一个内建函数result中,返回这个result函数,再执行.(有闭包,call/apply)

partialUsingArguments(test,a,b)(c,d);//用法

function partialUsingArguments(fn){
    var args1  = Array.prototype.slice.call(arguments,1);
    var result = function(){
        var args2 = Array.prototype.slice.call(arguments,0);
        var args = args1.concat(args2);
        return fn.apply(null,args);
    }
    return result;
}

  • 判断字符串是否连续重复(若是,则返回true)

function containRepeatingLetter(str){
    var re = /[a-zA-Z]/;
    for(var i = 0,len = str.length;i<len;i++){
        if(str.charAt(i) == str.charAt(i+1) && reg.test(str.charAt(i))){
    return true;
       }
    }
return false;
}


--------------------------------------------------------------------

  • 如下的结果是?

var m= 1, 
j = k = 0; 
function add(n) { 
    return n = n+1; 
  } 
y = add(m);   //4
function add(n) { 
    return n = n + 3; 
} 
z = add(m);   //4


所有声明的函数都会被提前。所以function add(){}定义的函数会优先解析,而不是顺序解析;因此整个过程中,首先依次解析两个add function,由于同名,所以后者会覆盖前者;然后,顺序解析其余的JS代码,y = add(m);语句和z = add(m); 语句调用的都是第二个add function,因此返回的都是4.

  • 如下的结果是?

 (function() {
          var a = b = 5;
      })();   
    console.log(b);  //5
    console.log(a);   //a is not defined
    
    

vara=b=5;其中var a表示a为当前作用域的全局变量,b=5并没有定义为当前作用域的全局变量,它会申明提前在全局作用域中。
可表示如下:

var b=5;
(function() {
      var a = b ;
  })();        
  console.log(b);  //5
  console.log(a);   //a is not defined      
  
  
  • 给出参数 str,start,end 表示当前字符串中从下标为 start 的字符开始的长度为 end
    的一个子串。你要将这个子串左右翻转后插在这个子串原来位置的正后方,求最后得到的字符串是什么。

  
 function reverseString(str,start,end){
     var slice = str.slice(start,end);
     var sliceReverse = slice.split('').reverse().join(''); //string -> array ->反array -> 反string
     var reverseString = str.slice(0,start+end)+sliceReverse+str.slice(start+end); //拼接新的字符串
     return reverseString;
}     
  • apply,bind(es5)结合,返回二维数组中每个一维数组的最大值

function largestOfFour(arr) {
  return arr.map(Function.apply.bind(Math.max, null));
}
largestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]]);

  • 用JS实现一个数组合并的方法(要求去重)。

var arr1 = ['a'];
var arr2 = ['b', 'c'];
var arr3 = ['c', ['d'], 'e', undefined, null];

var concat = (function(){
  // concat arr1 and arr2 without duplication.
  var concat_ = function(arr1, arr2) {
    for (var i=arr2.length-1;i>=0;i--) {
      arr1.indexOf(arr2[i]) === -1 ? arr1.push(arr2[i]) : 0;
    }
  };
  // concat arbitrary arrays.
  // Instead of alter supplied arrays, return a new one.
  return function(arr) {
    var result = arr.slice();
    for (var i=arguments.length-1;i>=1;i--) {
      concat_(result, arguments[i]);
    }
    return result;
  };
}());

  • 为字符串实现一个render方法,实现下面的变量替换功能

var greeting = 'my name is $(name),age $(age)';
var result = greeting.render({name:'XiaoMing',age:11});
console.log(result); // my name is XiaoMing,age 11

answer:

 String.prototype.render = function(option){
        var s = this,
                reg;
        Object.keys(option).forEach(function(k){
            reg = new RegExp("\\$\\("+k+"\\)","g");
            s = s.replace(reg,option[k])
        });
        return s
    };

    var greeting = 'my name is $(name),age $(age)';
    var result = greeting.render({name:'XiaoMing',age:11});
    console.log(result); // my name is XiaoMing,age 11

  • 取字符串中间的字符,奇数取1,偶数取2

function getMiddle(str){
   return str.substr(Math.ceil(str.length/2-1),str.length % 2 == 0 ? 2: 1)
 }
var p1 = getMiddle("test"); //es
    var p2 = getMiddle("testing"); //t
    var p3 = getMiddle("middle"); //dd
    var p4 = getMiddle("A"); //A
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值