zoukankan      html  css  js  c++  java
  • js笔试题系列之二——数组与对象

    (1)快速创建一个数组,数组中含有100个值为0元素。

    方法一:

    var arr = new Array(100);
    for(var i=0;i<100;i++){
      arr[i] = 0;
    }
    

    方法二:

    var arr = new Array(100);
    arr.join('0').split('');  //注意此方法结果0为字符类型
    

      面试官会喜欢哪个答案呢?

    (2)经典的数组去重问题

      数组去重可以说是各大公司前端笔试中的常见题,以下列出几种典型的解决方法

    方法一:传统双循环对比法

    function unique0(arr){
      var n = []; //一个新的临时数组
      for(var i=0,l=arr.length; i<l; i++) //遍历目标数组
      {
        var mark = 1; //标记字段
        for(var j=0;j<n.length+1;j++){ //遍历临时数组
          if(arr[i] === n[j]){
            mark = 0;
            break;
          }
        }         
        mark && n.push(arr[i]);
      }
      return n;
    }
    

    方法二:利用indexof方法 

    function unique1(arr){
      var n = []; //一个新的临时数组
      for(var i=0,l=arr.length; i<l; i++){ //遍历当前数组  
        //如果当前数组的第i已经保存进了临时数组,那么跳过,
        //否则把当前项push到临时数组里面
        if (n.indexOf(arr[i]) == -1) n.push(arr[i]);
      }
      return n;
    }
    

     方法三:利用对象属性唯一性

    function unique2(arr){
       var n = []; //存放新数组
       var json = {}; //利用对象属性唯一性
       for(var i=0,l=arr.length; i<l; i++){ //遍历当前数组
          if(!json[arr[i]]){ //判断json中是否有arr[i]属性
            n.push(arr[i]);
            json[arr[i]] = 1; //标记json新属性arr[i]
          } 
       }
       return n;
    }
    

      三种方法都有各自的优缺点,第一种方法利用双循环,所以当数组很大的时候效率是最低的,第二种利用了ES5的indexof方法,如果不考虑低版本IE的话(否则得先实现此方法)比较推荐,最后一种方法其实隐藏着一个BUG:由于这种方法利用的是对象属性唯一性,当给对象属性赋值为数组元素时,数组元素会被转换成字符串类型:unique2(['1,1',[1,1]])执行后返回了错误的结果["1,1"],也就是说此方法在多维数组场景下是不可行的。

    (3)删除给定数组的第二项和第三项,再将数组最后一个元素压入数组头部

      这里考察了数组操作的常用方法,我们以var arr = [1,2,3,4,5]为初始数组,先来看这个解答结果: 

    arr.splice(1,2).unshift(arr.pop()); ==>[1, 4]
    

      这种解决方法结果并不是我们期望的,因为按照题目的要求结果应该是[5,1,4],那么是哪里出问题了?原因就是这里不能以这种链式写法,因为splice方法的返回结果并不是原数组了,而是截取的数组片段,所以正确解答只需要这样改: 

    arr.splice(1,2);
    arr.unshift(arr.pop()); ==>[5,1,4]
    

    (4)填空题,实现输出['c','d']

    var data = {a:1,b:2,c:3,d:4};
    Object.keys(data).filter(function(x){
      return ______;
    })
    

      首先,你如果对Object.keys或者filter两个ES5新增方法不了解的话,这道题目就很难回答了。如果这两个方法都难不倒你,那你就离成功很近了,因为实际上只需要再下划线直接填写'x',就会返回['a','b','c','d'],那么如何让返回结果为['c','d']呢,聪明的你肯定已经想到了就是 x > 'b'。'c'、'd'和字符'b'比较结果为true所以能够返回,而'a'、'b'元素比较为false,不予返回。

    (5)代码实现如下要求

    var arr = [1,2];
    var new_arr;
    要求实现: 
    new_arr === arr ==>false
    new_arr[0] == arr[0]; ==>true
    new_arr[1] == arr[1]; ==>true
    

      这道题目先要看懂意思,了解出题者意图:题目要求new_arr不能严格等于arr,但是里面的元素是相等的。我们知道实现数组内元素相等很简单,在这里直接new_arr = arr就可以了,但是如果简单赋值则无法满足第一个条件,即两个数组不能严格相等。所以,出题者希望答题者了解的地方在于对对象引用赋值的了解、如何实现对象值传递而不是引用传递两个知识点。关于数组的值传递解决办法很简单,只需要遍历原数组的元素复制过去即可,当然这里不需要我们自己去写个遍历:

    var new_arr = arr.slice();
    //or
    var new_arr = arr.concat();
    

      上面两个方法都可以实现题目要求。

    (6)随机选取5-105中的10个不重复随机整数,然后按从小到大排序

      这里考了两个点,不重复随机数的获得、数字数组的排序,其中数组排列不能够直接用sort(),而必须传一个函数参数,否则将不能得到预期结果,因为数组排序默认是按照字符比较:

    方法一:

      var arr = []; //存放不重复随机数
      var n;
      while(arr.length < 10){
        n = Math.round(5+Math.random()*100);
        arr.indexOf(n)==-1&&arr.push(n);
      }
      arr.sort(function(a,b){return a-b});
      console.log(arr);
    

    方法二:

      var arr = []; //存放所有可能数
      for(var i=0;i<=100;i++){
        arr[i] = 5+i;
      }
      arr.sort(function(a,b){return 0.5 - Math.random();}).slice(0,10).sort(function(a,b){return a-b});
    

      方法二的思路和方法一明显不同,这里是把所有在范围区间的整数先存放在arr中,然后依次调用——sort(顺序打乱)——slice(取开头10个元素)——sort(按大小排序返回)

    (7)如何让所有浏览器兼容ES5的数组forEach方法

    Array.prototype.forEach || (Array.prototype.forEach = function(fun) {
      for (var i = 0; i < this.length; i++) {
        fun(this[i], i, this);
      }
    })
    

      先检测浏览器是否支持forEach,如果不支持则自己去写一个实现相同功能的同名方法,其它类似问题都可以按此思路解决。

    (8)深度克隆对象

    var cloneObj = function(obj){
        var str, newobj = obj.constructor === Array ? [] : {};
        if(typeof obj !== 'object'){
            return obj;
        } else if(window.JSON){
            str = JSON.stringify(obj), //系列化对象
            newobj = JSON.parse(str); //还原
        } else {
            for(var i in obj){
                newobj[i] = typeof obj[i] === 'object' ? 
                cloneObj(obj[i]) : obj[i]; 
            }
        }
        return newobj;
    };
    

      在js中对于对象的赋值,经常听到深拷贝和浅拷贝,浅拷贝就是直接对象赋值共同使用一个引用地址,但大多时候我们并不希望这样,而是希望对象之间能够完全独立,这个时候就需要深度克隆了,基本原理是对对象的所有属性进行遍历复制。

  • 相关阅读:
    HTML5 Input 类型
    Html5 web 储存
    解决json日期格式问题的3种方法(转载)
    Json格式串处理
    全局图片防盗链处理
    我的博客开张了
    iPhone手机屏幕分辨率
    通过CSS3伪类,美化Radio按钮样式
    测试用例 相关
    MongoDB基本命令
  • 原文地址:https://www.cnblogs.com/webLilingyun/p/5515334.html
Copyright © 2011-2022 走看看