最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 前端面试卷九

    正文概述 掘金(幸福的码农)   2020-12-06   382

    打印出 1 - 10000 之间的所有对称数

    //所谓对称数就是指从左到右遍历与从右到左遍历的结果一样,如121,不能是个位数
    function duiCheng()(
        Arrar(10000).keys().filter(index)=>{    //创建10000个元素的数组,keys就是0~9999的数组
            return index.toString().length > 1 &&    //排除个位数
                   index.toString().split('').reverse().join('') == index
        })
    )
    

    周一算法题之「移动零」

    给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非
    零元素的相对顺序。如输入: [0,1,0,3,12] 输出: [1,3,12,0,0]复制代码说明: 必须
    在原数组上操作,不能拷贝额外的数组。 尽量减少操作次数

    function moveZero(arr){
       var len = arr.length    //保存数组长度,每次将0移到最后,len减1,减少循环
       for(var i=0;i<len;i++){
           if(!arr[i]){
               arr.push(arr.splice(i,1))    //删除该元素,也就是0,放到数组末尾
               i--    //删除后i要减1才不会跳过下一个元素
               len--    //每次移动后,len减1,减少循环,末尾的0不需要遍历
           }
       }
       return arr
    }
    

    var、let 和 const 区别的实现原理是什么

    var 和 let 用以声明变量,const 用于声明只读的常量;
    var 声明的变量,不存在块级作用域,在全局范围内都有效,
    let 和 const声明的,只在它所在的代码块内有效;
    let 和 const 不存在像 var 那样的 “变量提升” 现象,所以 var 定义变
    量可以先使用,后声明,而 let 和 const 只可先声明,后使用;
    let 声明的变量存在暂时性死区,即只要块级作用域中存在 let,那么它

    所声明的变量就绑定了这个区域,不再受外部的影响。
    let 不允许在相同作用域内,重复声明同一个变量;
    const 在声明时必须初始化赋值,一旦声明,其声明的值就不允许改变,
    更不允许重复声明;如 const 声明了一个复合类型的常量,其存储的是一个引
    用地址,不允许改变的是这个地址,而对象本身是可变的。**
    变量与内存之间的关系,主要由三个部分组成:变量名 内存地址 内存空间**

    JS 引擎在读取变量时,先找到变量绑定的内存地址,然后找到地址所指向的内

    存空间,最后读取其中的内容。当变量改变时,JS 引擎不会用新值覆盖之前旧
    值的内存空间(虽然从写代码的角度来看,确实像是被覆盖掉了),而是重新
    分配一个新的内存空间来存储新值,并将新的内存地址与变量进行绑定,JS 引
    擎会在合适的时机进行 GC,回收旧的内存空间。const 定义变量(常量)后,
    变量名与内存地址之间建立了一种不可变的绑定关系,阻隔变量地址被改变,
    当 const 定义的变量进行重新赋值时,根据前面的论述,JS 引擎会尝试重新分
    配新的内存空间,所以会被拒绝,便会抛出异常。

    请实现一个 add 函数,满足以下功能

    add(1); // 1
    add(1)(2); // 3
    add(1)(2)(3);// 6
    add(1)(2, 3); // 6
    add(1, 2)(3); // 6
    add(1, 2, 3); // 6

    //要加工的函数:const add = (...args) => args.reduce((a, b) => a + b);
    //分析:柯里化操作(闭包收集参数),根据参数达没达到总的参数个数决定是收集还是调用
    
    //实现方法1:数组收集参数
    function curry(fn,length){    //fn=add函数,length=3
        var argArr = []    //收集参数
        return function result(...args){    //返回一个函数
            if(args.length+argArr.length>=length){    //如果参数收集完毕就执行
                return fn(...argArr,...args)    //执行函数
            }
            else{    //参数数量不够,小于3    如:add(1,2)
                argArr.push(...args)    //收集参数
                return result    //递归收集(3)
            }
        }
    }
    
    
    //实现方法2:利用bind具备收集参数的机制来实现参数收集
    //bind源码:
    Function.prototype.bind = function (context) {
        var self = this;    //调用的函数
        // 第 1 个参数是指定的 this,截取保存第 1 个之后的参数
        var args = Array.prototype.slice.call(arguments, 1); //(this,1,2)
        return function () {    //返回一个新函数
            // 此时的 arguments 是指 bind 返回的函数调用时接收的参数,(3):arguments就是3
          	// 类数组转成数组
            var bindArgs = Array.prototype.slice.call(arguments);
            //绑定this到context,这里参数是concat,就变成了[1,2,3]
            return self.apply( context, args.concat(bindArgs) );
        }
    }
    function curry(fn,length){    //fn=add函数,length初始为空,代表剩余参数个数
        length = length || fn.length    //length初始化为总的参数个数3
        return function(...args){    //返回一个函数
            if(args.length>=length){    //如果参数收集完毕就执行
                //fn经过bind之后把之前的参数已经收集,这里不需要cancat
                return fn.apply(this,args)    //执行函数
            }
            else{    //参数数量不够,小于3    如:add(1,2)
                //bind过的函数会收集参数
                curry(fn.bind(this,...args),length-args.length)    //递归调用,传递剩余参数个数
            }
        }
    }
    
    
    //实现方法3 直观写法,不返回
    function curry = fn => judge = (...args)=>{    包装fn函数为judge函数
        if(args.length > fn.length){    //如果参数收集完毕就执行
            return fn(...args)    //注意这里不需要return
        }
        else (...arg)=>judge(...args,arg)    //多阶函数,收集参数递归调用
    }
    

    react-router 里的link标签和a标签有什么区别

    如何禁掉 标签默认事件,禁掉之后如何实现跳转。

    Link 做了 3 件事情:
    1.有 onclick 那就执行 onclick: if (_this.props.onClick) _this.props.onClick(event);
    2.click 的时候阻止 a 标签默认事件(这样子点击就不会跳转和刷面:
    event.preventDefault();
    3.再取得跳转 href(即是 to),用 history(前端路由两种方式之一,history
    & hash)跳转,此时只是链接变了,并没有刷新页面

    周一算法题之「两数之和」

    给定一个整数数组和一个目标值,找出数组中和为目标值的两个数。你可以假设每个输入
    只对应一种答案,且同样的元素不能被重复利用。
    示例:给定 nums = [2, 7, 11, 15], target = 9 因为 nums[0] + nums[1] = 2 + 7 = 9
    所以返回 [0, 1]

    function answer(arr,target){    //target代表目标值9
        var map = {}    //用map保存遍历的数以及下表,我们只需要在剩余项中去找target-当前值
        for(var i=0;i<arr.length;i++){
            if(map[target-arr[i]]){    //遍历到7时,发现map[2]存在,直接返回结果即可
                return [map[target-arr[i]],i]
            }
            else{
                map[arr[i]] = i    //保存{2:0}到map中
            }
        }
    }
    

    在输入框中如何判断输入的是一个正确的网址。

    function isUrl(url){
        const a = document.createElement('a')    //创建a标签
        a.href= url
        return [
            /^(http|https):$/.test(a.protocol),    //必须是http或者https协议
            a.host,    //必须要有主机名
            a.pathName!=url,
            a.pathName!=`/${url}`
        ].find(x=>!x) == undefined    //去找不满足条件的,发现找不到,即全部满足证明url有效
    }
    

    实现 convert 方法,把原始 list 转换成树形结构,要求尽可能降低时间复杂度

    以下数据结构中,id 代表部门编号,name 是部门名称,parentId 是父部门编号,为 0 代表
    一级部门,现在要求实现一个 convert 方法,把原始 list 转换成树形结构,parentId 为多少
    挂载在该 id 的属性 children 数组下,结构如下:

    // 原始 list 如下 let list =[ 
        {id:1,name:'部门 A',parentId:0}, 
        {id:2,name:'部门 B',parentId:0}, 
        {id:3,name:'部门 C',parentId:1}, 
        {id:4,name:'部门 D',parentId:1}, 
        {id:5,name:'部门 E',parentId:2}, 
        {id:6,name:'部门 F',parentId:3}, 
        {id:7,name:'部门 G',parentId:2}, 
        {id:8,name:'部门 H',parentId:4}
    ]; 
    const result = convert(list, ...);
    // 转换后的结果如下 let result = [ 
        { id: 1, name: '部门 A', parentId: 0, children: [ 
                { id: 3, name: '部门 C', parentId: 1, children: [ 
                        { id: 6, name: '部门 F', parentId: 3 }, 
                        {id: 16, name: '部门 L', parentId: 3 } 
                    ] 
                },
                { id: 4, name: '部门 D', parentId: 1, children: [ 
                        { id: 8, name: '部门 H', parentId: 4 } 
                    ] 
                }
            ] 
        }, 
        ···
    ];
    

    实现代码:

    function convert(list){
       var res = []
       var map = list.forEach(item=>map[item.id] = item)    //构造map,key是id,value是整个对象
       for(var i=0;i<list.length;i++){
            var item = list[i]
            if(!item.parentId) {
                res.push(item)    //最上层的
                continue;
            }r
            if(map[item.parentId]){    //如果有父亲,就放入父亲的children中
                var parent = map[item.parentId]
                parent.children = parent.children||[]
                parent.children.push(item)
            }
       }
       return res
    }
    

    设计并实现 Peromise.race()

    //参数全部都是promse的情况
    Promise.prototype.race = function(promises){
        new Promise((resolve,reject)=>{    
            promises.forEach(promise=>promise.then(resolve,reject))    //谁先执行完成谁就先返回
        })
    }
    
    //参数实现了iterator接口的情况
    Promise._myrace = function(iterator){    //实现了iterator接口的集合
        return new Promise((resolve,reject)=>{
          try{
            let it = iterator[Symbol.iterator]()    //获取迭代器对象
            while(true){    //死循环,只要有一个执行完毕就结束循环
                let res = it.next()    //获取每一项
                if(res.done) break    //如果执行完毕
                if(res.value instanceof Promise)    //如果本身就是promise
                    res.value.then(resolve,reject)
                else 
                    resolve(res.value)    //done会置为true
            }
          }
          catch(err){
            reject(err)
          }
        })
    }
    

    实现模糊搜索结果的关键词高亮显示

    //v-html绑定计算属性,只要输入框输入内容变化就会替换v-html
    <template lang="">
      <span v-html="ruleTitle" ></span>
    </template>
    
    <script>
    export default {
      props: {
        item: '',
        searchVal: '',
      },
      computed: {
        ruleTitle() {
          let titleString = this.item;
          if (!titleString) {
            return '未知';
          }
          if (this.searchVal && this.searchVal.length > 0) {
                // 匹配关键字正则
            const replaceReg = new RegExp(this.searchVal, 'g');
                // 高亮替换v-html值
            const replaceString = `<span class="red">${this.searchVal}</span>`;
                // 开始替换
            titleString = titleString.replace(replaceReg, replaceString);
          }
          return titleString;
        },
      },
    };
    </script>
    

    起源地下载网 » 前端面试卷九

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元