美文网首页JavaScript学习笔记我滴学习Node
前端开发面试题总结之——JAVASCRIPT(三)

前端开发面试题总结之——JAVASCRIPT(三)

作者: sandisen | 来源:发表于2017-02-18 19:33 被阅读6255次

    相关知识点

    数据类型、运算、对象、function、继承、闭包、作用域、原型链、事件、RegExp、JSON、Ajax、DOM、BOM、内存泄漏、跨域、异步加载、模板引擎、前端MVC、前端MVVM、路由、模块化、Http、Canvas、jQuery、ECMAScript 2015(ES6)、Node.js、AngularJS、Vue、React......

    题目&答案

    • 函数记忆,判断是不是质数.
    方法一:
    function isPrime1(n){
          if(n<=3){return true}
          else{
            for(var i=2;i<Math.sqrt(n);i++){
              if(n%i==0){return false;}
            }
            return true;
          }
    };
    方法二:hash
        var isPrime2=(function(){//hash
          var hash={};
          return function(n){
            if(n<=3){return true}
            else if(hash[n]!==undefined){
              return hash[n];
            }else{
              for(var i=2;i<Math.sqrt(n);i++){
                if(n%i==0){return hash[n]=false}
              }
              return hash[n]=true;
            }
          }
    })();
    
    • 数组去重
    方法一:
    var arr1=[1,2,3,2,1,2];
        function repeat1(arr){
          for(var i=0,arr2=[];i<arr.length;i++){
            if(arr2.indexOf(arr[i])==-1){
              arr2.push(arr[i]);
            }
          }//(遍历结束)
          return arr2;
    }
    方法二:hash
    function repeat2(arr){
          //遍历arr中每个元素,同时声明hash
          for(var i=0,hash={};i<arr.length;i++){
           //hash中是否包含当前元素值的建
        //如果不包含,就hash添加一个新元素,以当前元素值为key,value默认为1
            if(hash[arr[i]]===undefined){
              hash[arr[i]]=1;
            }
          }//(遍历结束)
          //将hash转为索引:
          var i=0;
          var arr2=[];
          for(arr2[i++] in hash);
          return arr2;
    }
    方法三:
    function repeat3(arr){
          return arr.sort()
                   .join(",,")
                   .replace(
                    /(^|,,)([^,]+)(,,\2)*/g,
                    "$1$2")
                   .split(",,");
        }
     console.log(repeat3(arr1));
    
    • 插入排序
    var arr=[2,4,1,5,3];
        function insertSort(arr){
          //遍历arr中每个元素(i从1开始)
          for(var i=1;i<arr.length;i++){
            //将当前元素临时保存在变量t中
            var t=arr[i];
            var p=i-1;//声明变量p=i-1
            //循环:(arr[p]>t&&p>=0){
            while(arr[p]>t&&p>=0){
           //将p位置的值,赋值给p+1位置
              arr[p+1]=arr[p];
              p--;//p--
            }//(循环结束)
            arr[p+1]=t;//将t放在p+1的位置上
          }//(循环结束)
        }
        insertSort(arr);
    console.log(String(arr));
    
    • 快速排序:
        function quickSort(arr){
          //如果arr的length<=1
          if(arr.length<=1){
            return arr;//就直接返回arr
          }
          //计算参照位p
          var p=Math.floor(arr.length/2);
          var left=[];
          var right=[];
          //删除p位置的元素
          var center=arr.splice(p,1)[0];
          //遍历arr中每个元素
          for(var i=0;i<arr.length;i++){
            if(arr[i]>=center){
              right.push(arr[i]);
            }else{
              left.push(arr[i]);
            }
          }
          return quickSort(left) .concat(center,quickSort(right))
        }
        var sortedArr=quickSort(arr);
        console.log(String(sortedArr));
    
    • 正则表达式
    (1) "ryan5 is6 not7 a8 good9 man10"
    var n=5;
    var str="ryan is not a good man";
    str=str.replace(/\b[a-z]+\b/g,function(kw){ return kw+n++;});
    console.log(str);
    
    • 统计字符串中每种字符出现的次数,出现次数最多的是? 出现?次
        var str="helloworld";
        方法一:用hash
        for(var i=0,hash={};i<str.length;i++){
          if(hash[str[i]]){
            hash[str[i]]++
          }else{
            hash[str[i]]=1;
          }
        }
        console.dir(hash);
    方法二:用正则
    var arr=str.split("")
        .sort()
        .join("")
        .match(/([a-z])\1*/g)
        .sort(function(a,b){
    return b.length-a.length; })
    console.log("出现最多的是: "+arr[0][0]
        +"共"+arr[0].length+"次");
    var hash={};
        arr.forEach(function(val){
          hash[val[0]]=val.length;
        });
        console.dir(hash);
    
    • 数组降维
    var arr=[
          [0,0,0,0],
          [0,0,0,0],
          [0,0,0,0],
          [0,0,0,0],
        ];
        //method 1:
        for(var r=0,arr1=[];r<arr.length;r++){
          for(var c=0;c<arr[r].length;c++){
            arr1.push(arr[r][c]);
          }
        }
        console.dir(arr1);
        //method 2: 
        for(var r=0,arr2=[];r<arr.length;r++){
          arr2=arr2.concat(arr[r]);
        }
        console.dir(arr2);
      //method 3:
        var arr2=[].concat.apply([],arr);
        console.dir(arr2);
    
    • Function赋值
        var f=function(){var a=b=1;}
        f();
        console.log(b);//1
        console.log(a);//报错
        var f=function(){var a=b=1;}
        setTimeout(f,0);
        console.log(b);//报错
        f();
        var a,b=0, fn=function(){var a=b=2;}
        fn();
        console.log(a);//undefined
        console.log(b);//2
    
    • 函数currying(柯里华)
        var getN;
        function add(n){
          getN=function(){console.log(n);}
          return function(m){
            n+=m;
          arguments.callee.toString=function(){
              return n;
            }
            return arguments.callee;
          }
        }
        add(1)(2)(3); getN();//6
        add(1)(2)(3)(4); getN();//10
        alert(add(1)(2)(3));//6
        alert(add(1)(2)(3)(4));//10
    
    • 递归
    var emp={
       work:function(){//3,2,1
        var  sum=0;//+3+2+1 +2+1  +1
        for(vari=0; i<arguments.length&&arguments[0]>0;
              i++){
              sum+=arguments[i]
                  +arguments.callee(
                    --arguments[i]
                  );
            }
            return sum;
          }
        }
        console.log(emp.work(3,2,1));//10
    
    • 闭包
    (1)function fun(n,o){//外层函数
          console.log(o);
          return {
            fun:function(m){//内层函数 n
              return fun(m,n);
            }
          }
        }
        var a=fun(0);a.fun(1); a.fun(2); a.fun(3);
         //undefined  0      0       0
    var a=fun(0).fun(1).fun(2).fun(3);
    //undefined   0    1    2
    var a=fun(0).fun(1); a.fun(2); a.fun(3);
    //undefined  0       1      1
    (2)var a=0,b=0;
        function A(a){
          A=function(b){alert(a+b++)};
          alert(a);
        }
        A(1);//1
        A(12);//13
    
    • OOP
    (1)
    window.a=300;
        function fn1(){
          this.a=100;
          this.b=200;
          return function(){
                    alert(this.a)
                  }.call(arguments[0])
        }
        function fn2(){ this.a=new fn1(); }
    var a=new fn1().b;//300
    var v=new fn1(fn2());//[object Object]
    (2)
    var number=2;//4  8
        var obj={
          number:4,//8
          fn1:(function(){
            //var number;
            this.number*=2;
    number*=2; //声明提前  undefined
            var number=3;
            return function(){
              this.number*=2;
              number*=3;
              alert(number);
            }
          })()
        }
        var fn1=obj.fn1;
        alert(number); fn1(); obj.fn1(); 
        //4           9      27
        alert(window.number);//8
        alert(obj.number);//8
    (3)
    function Foo(){
        getName=function(){alert(1);};
          return this;
      }
      Foo.getName=function(){alert(2);};
      Foo.prototype.getName=function(){
        alert(3);
      };
      var getName=function(){alert(4);};
      function getName(){ alert(5); };
      Foo.getName();//2
      getName();//4
      Foo().getName();//1
      getName();//1
      new Foo.getName();//2
      new Foo().getName();//3
      new new Foo().getName();//3
    (4)
      var a=1;
      var b={
        a:2,
        b:function(){
          console.log(this.a);//1
        }(), 
        f:this.f=function(){
          console.log(this.a);
        }
      };
      function f(){ console.log(3); }
      f();//1
      b.f();//2
      (b.f)();//2
      (0,b.f)();//1
    (5)
      var foo=function(){
        console.log(this.a);
      }
      var obj={a:2,foo:foo};
      var a=10;
      var bar=obj.foo;
      var bar2=foo.bind(obj);
      bar();//10
      bar2();//2
      foo();//10
      obj.foo();//2
      setTimeout(bar,0);//10
    (6)
    function MyObj(){ 
        this.p.pid++; 
      }
      MyObj.prototype.p={"pid":0}//2
    MyObj.prototype.getNum=function(num){
        return this.p.pid+num;
      }
      var _obj1=new MyObj(); //创建新对象,继承原型pid+1
      var _obj2=new MyObj(); //创建新对象,继承原型pid+2
      console.log(
        _obj1.getNum(1)+_obj2.getNum(2)
      );//7      2+1   +    2+2
    
    • 判断一个对象是不是数组类型,有五种方法:
    (1) typeof 无法判断 只能判断原始类型的值和函数
    (2)isPrototypeOf 判断父及对象   可检查整个原型链 //可能继承自数组
        console.log(Array.prototype.isPrototypeOf([])?"是数组":"不是数组");
        console.log(Array.prototype.isPrototypeOf({})?"是数组":"不是数组");
        console.log(Array.prototype.isPrototypeOf(function(){})?"是数组":"不是数组");�
    (3)constructor 检查指定对象的构造函数 可检查整个原型链  //可能继承自数组
        var father={};
        var son={};
        father.__proto__=Array.prototype;
        son.__proto__=father;
        console.log(son.contructor==Array?"是数组":"不是数组")
        console.log({}.contructor==Array?"是数组":"不是数组");
        console.log(function(){}.contructor==Array?"是数组":"不是数组");�
    (4)instanceof 检查一个对象是否是制定构造函数的实例 可检查整个原型链 //可能继承自数组
        var father={};
        var son={};
        father.__proto__=Array.prototype;
        son.__proto__=father;
        console.log(son instanceof Array?"是数组":"不是数组");
        console.log({} instanceof Array?"是数组":"不是数组");
        console.log(function(){} instanceof Array?"是数组":"不是数组");
    (5)强行用要检查的对象,调用原始的toString方法  不检查整个原型链
            //[object class]: class-Array Date Object
            //只能检查最初就是数组创建的对象。
            console.log(Object.prototype.toString.call([])=="[object Array]"?"是数组":"不是数组");
            console.log(Object.prototype.toString.call({}));
            console.log(Object.prototype.toString.call(function(){}));
            console.log(Object.prototype.toString.call(/\d/));
            var father={};
             var son={};
             father.__proto__=Array.prototype;
             son.__proto__=father;
            console.log(Object.prototype.toString.call(son)=="[object Array]"?"是数组":"不是数组");//不是
            //结论: 对象一旦创建,class属性就无法修改
                   //修改继承关系,也无法修改class属性
    (6) Array.isArray(obj)  不检查整个原型链
            console.log(Array.isArray([]));
            console.log(Array.isArray({}));
        //如果浏览器不支持isArray
        if(Array.prototype.isArray===undefined){//if(!Array.isArray)
            //给?添加isArray方法
            Array.prototype.isArray=function(arg){
                //强行调用原始toString方法,和"[object Array]"比较
                return Object.prototype.toString.call(arg)
                =="[object Array]"?"是数组":"不是数组";
            }
        }
    
    • 自定义Object.create()——手写
        Object.create=function(father,props){
            console.log("我的create");
            /*使用setPrototypeOf方法
            var o=Object();//1. 创建空对象
            Object.setPrototypeOf(o,father);//2. 继承father
            */
            /*不使用setPrototypeOf方法
            function Constructor(){}
            Constructor.prototype=father;
            var o=new Constructor();
            */
            Object.defineProperties(o,props);//3. 定义新属性
            return o;
        }
    
    • 深克隆原理
    Object.clone=function(obj){//深克隆
    if(typeof(obj)=="object"){//如果obj是对象
        var o=//有必要区分数组和普通对象
        Object.prototype.toString.call(obj)=="[object Array]"?[]:{};
            for(var key in obj){//遍历obj的自有属性
                //如果key是obj的自有属性
                if(obj.hasOwnProperty(key)){
                    o[key]=arguments.callee(obj[key]);//arguments.callee调的是当前的Object.clone函数
                    }
            }
            return o;
            }else{//如果obj是原始类型的值,就直接返回副本
                return obj;
            }
        }
    
    • 如果浏览器不支持every属性,every的实现原理
        if(Array.prototype.every===undefined){
           Array.prototype.every=function(fun){
            //遍历当前数组中每个元素
            for(var i=0;i<this.length;i++){
                if(this[i]!==undefined){
    //调用fun,依次传入当前元素值,位置i,当前数组作为参数  ,将返回值,保存在变量r中
                var r=fun(this[i],i,this);
                if(r==false){//如果r为false
                   return false;//返回false
                }
                }
                 }//(遍历结束)
             return true;//返回true
           }
        }
    
    • 如果浏览器不支持some属性,some的实现原理
        if(Array.prototype.some===undefined){
           Array.prototype.some=function(fun){
              for(var i=0;i<this.length;i++){
              if(this[i]!==unefined){
                var r=fun(this[i],i,this);
                    if(r==true){ return true; }
                      }
                  }
              return false;
           }    
        }
    
    • 浏览器不支持map属性,map的实现原理
        if(Array.prototype.map===undefined){
           Array.prototype.map=function(fun){
            //创建空数组: newArr
            var newArr=[];
            //遍历当前数组中每个元素
            for(var i=0;i<this.length;i++){
               //如果当前元素不是undefined
               if(this[i]!==undefined){//判断稀疏数组
    //调用fun传入当前元素值,位置i,当前数组,将结果保存在r中
                    //将newArr的i位置赋值为r
                var r=fun(this[i],i,this);
                        newArr[i]=r;
               }
            }//(遍历结束)
            return newArr;//返回newArr
           }
        }
    
    • 如果浏览器不支持reduce属性,reduce的实现原理
        if(Array.prototype.reduce===undefined){
           Array.prototype.reduce=function(fun,base){
             base===undefined&&(base=0);
             for(var i=0;i<this.length;i++){
            if(this[i]!==undefined){
               base=fun(base,this[i],i,this);
            }
                 }
             return base;
               }
        }
    
    • 如果浏览器不支持bind属性, bind函数的实现原理
           if(Function.prototype.bind===undefined){
           Function.prototype.bind=function(obj/*,参数列表*/){
            var fun=this;//留住this
                    //*****将类数组对象,转化为普通数组
            var args=Array.prototype.slice.call(arguments,1);
            //args保存的就是提前绑定的参数列表
            /*function slice(1){
               var sub=[];
               for(var i=0;i<length;i++){
                sub.push(arguments[i]);
               }
               return sub;
            }*/
            return function(){
                       //将后传入的参数值,转为普通数组      
               var innerArgs=Array.prototype.slice.call(arguments);//将之前绑定的参数值和新传入的参数值,拼接为完整参数之列表
               var allArgs=args.concat(innerArgs)
              //调用原始函数fun,替换this为obj,传入所有参数
              fun.apply(obj,allArgs);
            }
           }
        }
    

    相关系列:
    前端开发面试题总结之——HTML
    前端开发面试题总结之——CSS3
    前端开发面试题总结之——JAVASCRIPT(一)
    前端开发面试题总结之——JAVASCRIPT(二)

    以上所有资料来源网络,如有不对的地方希望及时告知,谢谢!

    相关文章

      网友评论

      • 雨汐汐:第一个判断质数就是错误的,只怕耽误了其他人,好歹也测试一下
        你的 方法一:
        function isPrime1(n){
        if(n<=3){return true}
        else{
        for(var i=2;i<Math.sqrt(n);i++){
        if(n%i==0){return false;}
        }
        return true;
        }
        };
      • c1205b5421b5:好像都是培训班老师讲的吧,一个字你都不改,就当自己的啊
      • 易兒善:作为低端玩家,需要用的时候都是copy,只关注能不能用,没关注过怎么实现。瞬间觉得自己太low
      • 4b88d21bb9a2:作为前端大神,表示很简单🌝
        sandisen:@看书不瞌睡 +1: +1: +1: 大神可以忽略哦:
      • 听风看海:感觉挺不存,收藏了

      本文标题:前端开发面试题总结之——JAVASCRIPT(三)

      本文链接:https://www.haomeiwen.com/subject/cqhdwttx.html