美文网首页
前端面试宝典

前端面试宝典

作者: 拾钱运 | 来源:发表于2019-10-08 19:13 被阅读0次

    1.作用域

    <script>
      var num1=55;
      var num2=66;
    function fn(num,num1){
      num=100;
      num1=100;
      num2=100;
    console.log(num)
    console.log(num1)
    console.log(num2)
    }
    fn(num1,num2) // 100  100  100
    console.log(num1) //55 在fn中改变的num1是形参
    console.log(num2) //100  在函数中没有声明num2,改变的就是num2
    console.log(num)//报错
    </script>
    

    2.值类型引用类型的传值

    image.png
    function Person(name,age,salary){
      this.name=name;
      this.age=age
      this.salary=salary
    }
    function f1(person){
      //var person=p  隐形
    person.name='ls';
    pserson=new Person('aa',18,10)
    }
    var p=new Person('zs',18,1000)
    console.log(p.name);//zs
    f1(p)  //执行这个函数的时候,开始person=p对象,后来创建了person,person换了指针方向(如上图),name=aa  和原来的p对象没有关系
    console.log(p.name)//ls
    

    3.已知有字符串foo='get-element-by-id',写一个function将其转化成驼峰表示法“getElementById”

    <script>
        var foo='get-element-by-id'
        function toString(foo){
            var arr=foo.split('-')
            for(let i=1;i<arr.length;i++){
              arr[i]=arr[i].charAt(0).toUpperCase()+arr[i].substr(1,arr[i].length-1)
            }
          return arr.join('')
        }
    var s=toString(foo)
    console.log(s)
    </script>
    

    12.js综合面试题

    题目

      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();
    getName()
    Foo().getName()
    getName()
    new Foo.getName()
    new Foo().getName()
    new new Foo().getName()
    
    //输出结果为:2,4,1,1,2,3,3
    

    解析

    //首先代码执行完结构变成
      function  Foo(){
         getName=function (){alert(1)}
          return this
     }
    //var  getName; //变量提升,函数提升
    //function getName(){  //突然碰到了与变量相同的函数,就会保留这个函数,继续往下执行
     // alert(5)
    //} 
    Foo.getName=function(){
      alert(2)
    }
    Foo.prototype.getName=function(){
      alert(3)
    }
    //走到这里的时候发现了与上面的函数名字相同就会覆盖上面的面
    getName=function () {
      alert(4)
    }
    //由此代码执行完,开始调用
    
    • Foo.getName() 无疑就是执行的 输出2


      image.png
    • getName() 输出4
    • Foo().getName()
    //这个时候先执行的是Foo() .Foo()函数中返回了this,指向的window,然后.getName()  执行的就是
    function Foo(){
      getName=function(){alert(1)}
    return this
    }
    //输出1,这个时候有个作用域的问题,全局变量中也有一个getName变量的函数,所以会被覆盖,此时代码结构为
    //首先代码执行完结构变成
      function  Foo(){
         getName=function (){alert(1)}
          return this
     }
    //var  getName; //变量提升,函数提升
    //function getName(){  //突然碰到了与变量相同的函数,就会保留这个函数,继续往下执行
     // alert(5)
    //} 
    Foo.getName=function(){
      alert(2)
    }
    Foo.prototype.getName=function(){
      alert(3)
    }
    //走到这里的时候发现了与上面的函数名字相同就会覆盖上面的面
    /*getName=function () {
      alert(4)
    }*/
    getName=function(){
      alert(1)
    }
    //这个时候习性getName()
    
    • getName() 输出1
    • new Foo.getName() 此时.的优先级高,所以先执行Foo.getName() 是2,然后 new (function (){alert(2)}) 没有太大作用,因为没有用这个对象
    • new Foo().getName() 输出3
      这个时候没有办法先执行. 所以先执行new Foo() 创建了一个对象 然后 foo.getName() 这个时候,就是原型链的知识点了,foo这个对象本身新创建出来的没有foo.getName()所以要从这个对象的proto 也就是这个构造器(Foo)的prototype中查找
      此时执行的是
    Foo.prototype.getName()=function(){
      alert(3)
    }
    
    • new new Foo().getName() 输出3
      当前和上面的类似 new (new Foo().getName())

    13.函数节流和防抖

    什么是函数节流
    一个函数执行一次后,只有大于设定的执行周期后才会执行第二次

    • 有个需要频繁触发函数,出于优化性能角度,在规定时间内,只让函数触发的一次生效,后面的不生效
    /**
    节流函数   使用闭包是为了避免每次执行这个函数的时候lastTime总是初始化0,这样的话lastTime会每次记录上一次的执行时间,因为闭包内的变量不会执行完销毁
    @param  fn   要节流的函数
    @param   delay  规定的时间
    */
    function throttle(fn,delay){
      //记录上一次函数触发的时间
        var lastTime=0;
        return  function(){
         //记录当前时间
         var nowTime=Date.now()
          if(nowTime-lastTime>delay){
            fn.call(this)  
            lastTime=nowTime
          }
       }
    }
    

    防抖函数
    一个需要频繁触发,在规定时间内,只让最后一次生效,前面的不生效

    function debounce(fn,delay){
    //记录上一次的延时器
      var timer=null;
       return function(){
        clearTimeout(timer);
        timer=setTimeout(function(){
            fn.apply(this)
       },delay)
      } 
    }
    

    16.从url输入网址到渲染页面完成,发生了什么?

    1.DND解析;将域名地址解析为ip地址
    - 浏览器DNS解析
    - 系统DNS解析
    -路由器DNS缓存
    -网络运营商DNS缓存
    -递归搜索:blog、baidu、com

    • .com域名下查找DNS解析
    • .baidu域名下查找DNS解析
    • blog域名下查找DNS解析

    19.宏任务和微任务

    宏任务:
    分类:setTimeout setInterval requirestAnimationFrame
    1.宏任务所处的队列就是宏任务队列
    2.第一个宏任务队列中只有一个任务,执行主线程的js代码
    3.宏任务队列可以有多个
    微任务:
    分类:new promise().then(回调) process.nextTick()
    1.微任务所处的队列就是微任务队列
    2.只有一个微任务队列
    3.在上一个宏任务队列执行完毕之后如果有微任务队列就会执行微任务队列中的所有任务

    console.log('----------------start---------------')
    setTimeout(()=>{
      console.log('setTimeout')
    },0)
    new  Promise((resolve,reject)=>{
      for(var i=0;i<5;i++){
          console.log(i)
      }
    resolve();
    }).then(()=>{
      console.log('promise实例成功回调执行')
    })
    console.log('-----------------end--------------------')
    
    //执行结果   
    start、0 1 2 3 4 5 、 end  、promise实例成功回调执行、  setTimeout
    宏任务  :同步执行的代码 两个start  、end  和promise  里面的循环
    第二个宏任务队列:setTimeout 
    微任务队列:promise成功调用   
    
    当第一个宏任务队列执行完成之后,执行微任务队列,然后在执行其他的宏任务队列
    
    image.png

    25.vuex管理状态的机制

    image.png
    vuex由五部分组成:
    state 单一状态树
    getter 相当于计算属性,将他的依赖缓存起来,以来至发生改变的时候才会重新计算
    mutation 直接改变state中的值
    action 异步改变state中的值,
    module 模块,每个模块可以拥有单独的state,mutation,action,getter

    26.vue的MVVM实现原理

    image.png

    通过observer监视、劫持data中所有对象的属性,有多少个属性创建多少个dep,当数据属性改变的时候,observer通知对应的某个dep,dep通知所有相关的watcher,watcher是在编译模板complie为每个表达式创建对应的watcher,同时指定了更新节点的回凋函数,将所有的watcher添加到所有对应的dep中。当通知了watcher的时候,更新界面。

    27. 将{name:'zmq',age:25,address:'北京'}转变成[{name:'zmq'},{age:25},{address:'北京'}]

    考察点:Object.keys():将一个对象的值转换成数组 Array.map((key)=>{

    //key对象的键
    })数组的遍历
    个人解析:Object.keys(person)此时结果为["name", "age", "address"]
    然后就可以用map了,然后再 pArr.push({key:person[key]})即可

      let person={
                name:'zmq',
                age:25,
                address:'北京'
            }
            let pArr=[]
         Object.keys(person).map((key)=>{
                pArr.push({key:person[key]})
            })
            console.log(pArr)
    

    28.介绍一下盒子模型和ie模型的区别

    标准盒子模型:宽度=content+pandding+margin+border
    ie盒子模型=content(padding+border)+margin

    29.css选择器有哪些,哪些属性可以继承

    Id选择器 #id类选择器 .class 标签选择器 div ,p 相邻选择器 div +p 子选择器 div >p
    属性选择器的a[rel =“external”] 后代选择器 div p 通配符选择器 * 伪类选择器 a:hover,li:nth-child

    可继承的属性 font-size ,font-family Color
    不可继承的属性 border padding margin width height

    优先级 就近选择。
    !important>Id>Class>Tag
    !important大于内联样式

    30、css优先级算法如何计算的

    元素选择符 1
    class 10
    Id 100
    元素标签 1000
    1.!important 声明的样式优先级最高,如果有冲突再去计算

    2.如果优先级相同,选择最后出现的声明往事
    3.继承的样式的优先级最低

    31、css书写顺序

    1)定位属性:position display float left top right bottom overflow clear z-index

    (2)自身属性:width height padding border margin background

    (3)文字样式:font-family font-size font-style font-weight font-varient color

    (4)文本属性:text-align vertical-align text-wrap text-transform text-indent text-decoration letter-spacing word-spacing white-space text-overflow

    (5)css3中新增属性:content box-shadow border-radius transform……

    目的:减少浏览器reflow(回流),提升浏览器渲染dom的性能
    原理:https://blog.csdn.net/weixin_43365995/article/details/108119760

    相关文章

      网友评论

          本文标题:前端面试宝典

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