资讯专栏INFORMATION COLUMN

js面试题

dack / 2893人阅读

摘要:文章中如果有错误或者有更好的解法,请多多指出。它类似于数组,但是成员的值都是唯一的,没有重复的值。

文章中如果有错误或者有更好的解法,请多多指出。

1.字符串去重

思路:(1)利用对象key值唯一性

function unique(str){
      var _obj=str.split("");
        var length=str.length;
        var result="";
        var obj={};
        for(var i=0;i

(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

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
function distinct(ary){
    var obj={};
    for(var i=0;i

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

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)

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/93477.html

相关文章

  • 你不能错过的前端面试合集

    摘要:收集的一些前端面试题从面试题发现不足,进而查漏补缺,比通过面试更难得及各大互联网公司前端笔试面试题篇及各大互联网公司前端笔试面试题篇面试题个和个经典面试题前端开发面试题如何面试前端工程师很重要个变态题解析如何通过饿了么面试轻 收集的一些前端面试题 从面试题发现不足,进而查漏补缺,比通过面试更难得 1 BAT及各大互联网公司2014前端笔试面试题--Html,Css篇 2 BAT...

    ninefive 评论0 收藏0
  • 你不能错过的前端面试合集

    摘要:收集的一些前端面试题从面试题发现不足,进而查漏补缺,比通过面试更难得及各大互联网公司前端笔试面试题篇及各大互联网公司前端笔试面试题篇面试题个和个经典面试题前端开发面试题如何面试前端工程师很重要个变态题解析如何通过饿了么面试轻 收集的一些前端面试题 从面试题发现不足,进而查漏补缺,比通过面试更难得 1 BAT及各大互联网公司2014前端笔试面试题--Html,Css篇 2 BAT...

    darkbaby123 评论0 收藏0
  • 前端最强面经汇总

    摘要:获取的对象范围方法获取的是最终应用在元素上的所有属性对象即使没有代码,也会把默认的祖宗八代都显示出来而只能获取元素属性中的样式。因此对于一个光秃秃的元素,方法返回对象中属性值如果有就是据我测试不同环境结果可能有差异而就是。 花了很长时间整理的前端面试资源,喜欢请大家不要吝啬star~ 别只收藏,点个赞,点个star再走哈~ 持续更新中……,可以关注下github 项目地址 https:...

    wangjuntytl 评论0 收藏0
  • 前端开发面试链接

    摘要:手册网超级有用的前端基础技术面试问题收集前端面试题目及答案汇总史上最全前端面试题含答案常见前端面试题及答案经典面试题及答案精选总结前端面试过程中最容易出现的问题前端面试题整理腾讯前端面试经验前端基础面试题部分最新前端面试题攻略前端面试前端入 手册网:http://www.shouce.ren/post/index 超级有用的前端基础技术面试问题收集:http://www.codec...

    h9911 评论0 收藏0
  • 前端开发面试链接

    摘要:手册网超级有用的前端基础技术面试问题收集前端面试题目及答案汇总史上最全前端面试题含答案常见前端面试题及答案经典面试题及答案精选总结前端面试过程中最容易出现的问题前端面试题整理腾讯前端面试经验前端基础面试题部分最新前端面试题攻略前端面试前端入 手册网:http://www.shouce.ren/post/index 超级有用的前端基础技术面试问题收集:http://www.codec...

    snifes 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<