js面试题

文章中假如有毛病或许有更好的解法,请多多指出。

1.字符串去重

思绪:(1)应用对象key值唯一性

function unique(str){
      var _obj=str.split('');
        var length=str.length;
        var result='';
        var obj={};
        for(var i=0;i<length;i++){
            if(!obj[_obj[i]]){
               obj[_obj[i]]='abc';
                result+=_obj[i]
            }
        }
        return result;
    }
    var str='oooooooooooopppppppppppppollllllllllsssssssss'
    console.log(unique(str))

(2)要领2 应用Set (感谢道友们的分享)
ES6供应了新的数据构造Set。它类似于数组,然则成员的值都是唯一的,没有反复的值。

const unique = str => [...new Set(str.split(""))].join("");

var str='oooooooooooopppppppppppppollllllllllsssssssss'
console.log(unique(str)) // opls

2.查找出在字符串中只涌现一次的第一个字符

举例-str=’pppwrtto’ ===> 输出 w
思绪:
1.str去重 [p,w,r,t,o] 同时将字符涌现的次数记录下来,构成以下构造
{p:3,w:1,r:1,t:2,o:1}
2.推断当第一次obj[key]==1的时刻就返回key值

function firstUnique(str){
    var arr=str.split('');
      var length=arr.length;
      var obj={};
      var num=0;
      for(var i=0;i<length;i++){
          if(!obj[arr[i]]){
              obj[arr[i]]=1;
              num++;
          }else{
             for( key in obj){
                 if(key==arr[i]){
                     obj[key]+=1;
                 }
             }
          }
      }
      for(key in obj){
          if(obj[key]==1){
              return key;
          }
      }
  }
    var str='wwccbbeeooppkkd'
    console.log(firstUnique(str))

3.封装typeof(重点辨别 援用值—1.数组,2.对象,3.包装类)
思绪:1.辨别原始值 援用值 2.原始值 援用值

function type(target){
        //原始值 援用值
        //辨别援用值
        var template={
            "[object Array]":'array',
            "[object Object]":'object',
            "[object Number]":'number-object',
            "[object Boolean]":'boolean-object',
            "[object String]":'string-object'
        }
        if(target===null){
            return 'null';
        }else if(typeof(target)=='object'){
            // 数组
            // 对象
            // 包装类 Object.prototype.toString
            var str=Object.prototype.toString.call(target);
            return template[str];
        }else{
            return typeof(target)
        }
    }
    console.log(type('abc'))
    console.log(type(function(){}))
    console.log(type([]))
    console.log(type({}))
    console.log(type(new Number()))
    console.log(type(new Object()))
    console.log(type(new String()))
    console.log(type(new Boolean()))
    console.log(type(new Array()))

4.数组去重–在原型链上举行
var arr=[1,1,2,2,’a’,’a’]
arr.unique–>[1,2,a]
思绪:经由过程对象 hash体式格局

Array.prototype.unique=function(){
        var obj={};
        var result=[];
        var length=this.length;
        for(var i=0;i<length;i++){
            if(!obj[this[i]]){
                obj[this[i]]='unique';
                result.push(this[i])
            }

        }
        return result;
    }
    var s=[1,1,1,1,1,2,2,4,4,4,5,5,5];
    console.log(s.unique())

function distinct(ary){
    var obj={};
    for(var i=0;i<ary.length;i++){
        var item=ary[i];
        if(typeof obj[item]!=='undefined'){
          ary[i]=ary[ary.length-1];
          ary.length--;
          i--;
          continue;
      }
      obj[item]=item;
   }
   obj=null;
   return ary;
}
var ary=[1,2,3,2,1,3]
console.log(distinct(ary))

5.Js完成要领一连挪用

var demo={
        smoke:function(){
            console.log("抽烟")
            return this;
        },
        eat:function(){
            console.log('用饭')
            return this;
        },
        perm:function() {
            console.log('烫头')
            return this;
        }
    }
    demo.smoke().eat().perm()

6.低耦合写出阶乘函数
–消弭严密耦合的征象,能够像下面如许运用 arguments.callee(严厉形式下callee失效)

function factorial(num){
        if(num<=1){
            return 1;
        }else{
            return num*arguments.callee(num-1)
        }
    }
    console.log(factorial(3))

7.&&与||运算符

 var a=1&&2; //&& 假如第一个表达式为真,将返回第二个表达式值返回
    console.log(a);
    var b=1&&2+2;
    console.log(b);
    var c=0&&2; //&& 假如第一个表达式为假,将返回第一个表达式值返回
    console.log(c)
    var d=1||2;//|| 第一个表达式为真,则直接返回
    console.log(d)
    var e=0||2;//|| 第一个表达式为假,则返回第二个值
    console.log(e)

    2>1&&document.write('hello');
    var data;
    data&&console.log('ni hao')

8.浅拷贝

我们晓得援用范例的赋值实际上是转变了变量的指向,那末假如在须要拷贝的对象中存在某个属性的值是援用范例,如数组或子对象,那末浅拷贝后的原对象的属性取得的也只是这个指向。所以假如转变被拷贝对象的属性值,那末原对象的响应属性也会随着转变

  function extendCopy(p) {
    var c = {};
    for (var i in p) { 
      c[i] = p[i];
    }
    c.uber = p;
    return c;
  }

9.深拷贝
递归

  function deepCopy(p, c) {

    var c = c || {};

    for (var i in p) {

      if (typeof p[i] === 'object') {

        c[i] = (p[i].constructor === Array) ? [] : {};

        deepCopy(p[i], c[i]);

      } else {

         c[i] = p[i];

      }
    }

    return c;
  }
  var chinese={
       nation:'中国',
       minzu:{name1:'汉族',name2:'苗族'}
     }
 var Doctor = deepCopy(Chinese);

数组&对象深拷贝

function deepCopy(origin) {
    if (typeof origin != 'object') {
        return origin;
    }
    var result;
    if(Object.prototype.toString.call(origin)=== '[object Array]'){
        result=[];
        for(var i in origin){
            result[i]= typeof origin[i]==='object'?deepCopy(origin[i]):origin[i];
        }
    }else{
        result={};
        for (var key in origin) {
            if(origin.hasOwnProperty(key)){
                result[key]= typeof origin[key]==='object'?deepCopy(origin[key]):origin[key];
            }
        }
    }
    return result;
}
    var obj1={
        name:'小黄',
        sister:{name:'花花',age:20},
        grade:[10,20,30,[89,60]]
    };
    var obj2=deepCopy(obj1)

10.函数预编译 GO与AO
终究
GO{

a:100,
demo:function(){},
f:123

}
AO{

e:2,
b:undefined,
a:10

}

 a=100;
    function demo(e){
        function e(){}
        arguments[0]=2;
        console.log(e); //2
        if(a){
            var b=123;
        }
        a=10;
        var a;
        console.log(b);//undefined
        f=123;
        console.log(a);//10
    }
    var a;
    demo(1);
    console.log(a); //100
    console.log(f); //123

11.将 var obj={value0:’1′,remark0:’备注1′,value1:’2′,remark1:’备注2′}; 转换为[{value0:’1′,remark0:’备注1′},{value1:’2′,remark1:’备注2′}]

    var obj={value0:'1',remark0:'备注1',value1:'2',remark1:'备注2'};
    var count=0;
    var result=[];
    var storage={};
    for(var key in obj){
        count++;
        storage[key]=obj[key]
        if(count%2==0){
            result[count/2-1]=storage;
            storage={};
        }
    }
    console.log(result);

12.输入一个整形数组,数组中有正数也有负数,数组中一连的一个或多个数组构成一个子数组,每个子数组都有一个和,求一切子数组和的最大值。

  var s=[20,[1,2,10],[-2,30,[-1,-1,-8]]];
    function max(origin){
        var length=origin.length;
        var array=[]
        for(var i=0;i<length;i++){
            array[i]=sum(origin[i])
        }
        array.sort(function(a,b){
            return a-b;
        })
        return array[array.length-1]
    }
    function sum(item){
        var isArray=item.constructor===Array;
        var _sum=0;
        if(isArray){
            for(var i=0;i<item.length;i++){
                _sum+=item[i].constructor===Array?sum(item[i]):item[i];
            }
            return _sum;
        }else{
            return item;
        }
    }
    console.log(max(s))

13、call道理以及口试题
道理:

Function.prototype.call=function call(context){
   //native code
   //把指定函数中的this指向context =>也就是fn this转变 -------[把this(call中的this)中的this指向context]
   //把指定函数实行 fn实行---- [this实行] this()
}
//以下都是让call要领实行
//fn.call(opp)  //call要领中的this 是fn
//fn.__proto__.call();  //call要领中的this是fn.__proto__
//Function.prototype.call(); //call this=>Function.prototype

问题:

function fn1(){
  console.log(1);
}
function fn2(){
  console.log(2)
}
fn1.call(fn2);
//fn1.call :fn1这个Function的实例经由过程__proto__找到Function.prototype上的call要领,然后让call要领实行(通报fn2这个实参)  
//实行call的时刻,call中的this:fn1,所此处是把fn1实行,让fn1中的this实行fn2
fn1.call.call.call(fn2);
//f1.call.call.call 依然是找到原型上的call要领而且让call实行。
//  call3中的this:fn1.call.call[原型上的call]
//  call3中的Context:fn2

// 1.  让【原型中的call(fn1.call.call)】中的this指向fn2
// 2. 让[原型上的call(fn1.call.call)]实行 
//    -1、第二次实行原型上的call,只不过此时的call已变成了fn2
//   -2、让指定函数fn2中的this指向undefined
//     -3、让fn2实行
Function.prototype.call(fn2);
//  找到原型上的call要领,让call实行
//    call实行:
//    this:Function.prototype
//    context:fn2
//
//   把Functon.prototype中的this关键字变成fn2
//   让Function.prototype实行
//   ==>无输出(匿名空函数实行无输出)
Function.prototype.call.call.call(fn2);
// 等价于 fn1.call.call.call(fn2)

14、阿里口试问题

    function Foo(){
        getName=function(){
            console.log(1)
        };
        return this;
    }
    Foo.getName=function(){
        console.log(2);
    }
    Foo.prototype.getName=function(){
        console.log(3)
    }
    var getName=function(){
        console.log(4)
    }
    function getName(){
        console.log(5)
    }
    Foo.getName() //把Foo作为对象,找其私有属性
    getName();// 实行全局下的getName
    Foo().getName(); //先将Foo作为一般函数实行,然后在调取getName
    getName();
    new Foo.getName()//先猎取Foo.getName的值(假定B),然后在new B()相当于建立B的实例
    new Foo().getName() //先new Foo() 猎取实例(new Foo()相当于将Foo函数有从新实行了一遍,此时getName->1),把获得的实例再调取getName

    new new Foo().getName();//=>var f=new Foo() new f.getName() =>[new (f.getName)]()

15、数组去重《链式写法》

Array.prototype.myDistinct=function myDistinct(){
    var obj={};
    for (var i = 0; i < this.length; i++) {
        var item=this[i];
        if(typeof obj[item]!=='undefined'){
            this[i]=this[this.length-1];
            this.length-1;
            i--;
            continue;
        }
        obj[item]=item;
    }
    obj=null;
    return this;
}
    var ary=[1,2,3,4,1,2,44,3]
    ary.myDistinct();
    ayy.myDistinct.sort();

16.闭包、作用域、变量提拔

 var num=1,
        obj={
            num:2,
            fn:(function(num){
                this.num*=2;
                num+=2;
                return function(){
                    this.num*=3;
                    num++;
                    console.log(num)
                }
            })(num)
        }
    var fn=obj.fn;
    fn();
    obj.fn();
    console.log(num,obj.num)
    原文作者:Francis
    原文地址: https://segmentfault.com/a/1190000013788907
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞