上周去面了两家公司,part1是第一家公司的部分试题,part2是第二家公司的部分试题

Part 1

  1. 手写一个类和类的继承?扩展一下class中属性和方法的写法和class继承的用法。

    // Animal, Dog, Cat  Animal是父类,Dog和Cat都是Animal的子类
    // Dog打印 我是贵宾狗,我叫小黑,我6岁,我喜欢吃骨头。
    // Cat打印 我是木偶猫,我叫小白,我7岁,我喜欢吃鱼
    
    /* 
    分析一下: 公共的有名字(name),年纪(age),喜欢吃的食物(food)
    */
    
    class Animal{
      constructor(name, age, food) {
        Object.assign(this, {name, age, food});
      }
      basicInfo(){
        return `我叫${this.name},我${this.age}岁,我喜欢吃${this.food}`
      }
    }
    
    class Dog extends Animal{
      constructor(name, age, food, type) {
        super(name, age, food )
        this.type = type
      }
      log(){
        console.log(`我是${this.type},${super.basicInfo()}!`)
      }
    }
    
    class Cat extends Animal{
      constructor(name, age, food, type){
        super(name, age, food)
        this.type = type
      }
      log(){
        console.log(`我是${this.type},${super.basicInfo()}!`)
      }
    }
    
    // (name, age, food, type)
    let an = new Animal("小红",6, "饭")
    let dog = new Dog("小黑", 6, "骨头", "贵宾狗")
    let cat = new Cat("小白", 7, "鱼", "木偶猫")
    
    console.log(an.basicInfo());
    dog.log()
    cat.log()
    // 我叫小红,我6岁,我喜欢吃饭
    // 我是贵宾狗,我叫小黑,我6岁,我喜欢吃骨头!
    // 我是木偶猫,我叫小白,我7岁,我喜欢吃鱼!

    遇到这样,要写类和继承的题,分析步骤是:

    • 找出父类和子类中的公共属性和方法,作为父类的属性和方法
    • 找出子类中独有的属性和方法,作为子类的属性和方法
    • 根据归类好的属性和方法,写父类和子类;父类直接 class 定义, 子类继承父类用extends
    • constructor中,子类需要多少属性,就传参多少个,来自父类的属性,用super方法处理,再将其他的属性赋给this对象
    • 子类的方法中,需要用到父类方法时,用super对象调用
  2. 下面的函数输出什么?

    含 new Promise,setTimeOut

    setTimeout(() => {
      console.log("hello");
    }, 100);
    
    new Promise((resolve, reject) => {
      console.log(1);
      resolve("a");
    }).then((res) => {
      console.log(res);
      console.log("resolved");
    }).catch(()=> {
      console.log(3);
    })
    console.log("finished");

    打印结果: 1 finished a resolved hello

    分析:

    • setTimeout下一轮事件循环开始时执行 所以 hello 最后打印。
    • Promise创建后,马上执行, 打印1
    • Promisethen方法是当前脚本的所有同步任务执行完了之后,也就是本轮事件循环结束时执行,打印 finished
    • Promise构造函数的两个参数分别是 resolve和reject,resolve会将promise实例的状态置为fulfilled(完成),然后代码就不会往下执行。接着代码就会走到then方法中,then方法中的参数,就是resolve的结果,当resolve中参数一个非promise时,res就是这个参数本身 打印a resolved
  3. css3的几个属性 translate,transform,transition,animation。拓展:几个css3特效的用法。

    这几个属性的区别 区别说明的网站

    translate用法:

    • translatetransform的一个属性。translate方法传两个参数left,top,表示沿x轴和y轴的移动的距离。 translate(0, -50%) 表示沿y轴向上移动 50%

      transform用法:

    • 变形改变。包括旋转(rotate)、扭曲(skew)、缩放(scale)、移动(translate), matrix。起点位置为 transform-origin: bottom left;

      看例子:

      <style>
      .box{
        width: 0;
        height: 0;
        border-top: 0;
        border-left: 100px solid transparent;
        border-right: 100px solid transparent;
        border-bottom: 100px solid rgb(193, 240, 195);
        /* 上面画一个三角形 */
        cursor: pointer;
        margin: 200px 0 0 200px;
      }
      </style>
      <body>
        <div class="box" onclick="handleChange()">我是box</div>
        <script>
          let i = 1
          function handleChange(){
            let ele = document.querySelector(".box") // 返回当前文档中第一个类名为 "box" 的元素
            /* let deg = i % 2 ? 90 : 0
            ele.style.transform = `rotate(${deg}deg)` */
      
            /* let scale = i % 2 ? "0.8,0.5" : "0.3,0.3"
            ele.style.transform = `scale(${scale})` */
      
            let skew = i % 2 ? "20" : "-20"
            ele.style.transform = `skew(${skew}deg)`
            i ++
          }
        </script>
      </body>

transition的用法

  • transition 属性是四个属性的缩写 transition-propertytransition-duration, transition-timing-function, transition-delay。分别表示:过渡效果的css属性名称完成过渡效果需要的秒或毫秒、速度效果的速度曲线、过渡效果何时开始

    transition 属性是这四个属性是顺序往后排。第一个transition-propertytransition-duration是必填。transition-timing-function的可选项是: linear(匀速),ease(慢速开始-快-慢速结束),ease-in(慢速开始), ease-out(慢速结束), ease-in-out(慢速开始和结束的)

    基于上面的例子,可以把 transition和transform放在一起用:

    // 点击box时,1秒之后,在0.5s时间内,先快后慢,顺时针旋转90°  
    function handleChange(){
      let ele = document.querySelector(".box") // 返回当前文档中第一个类名为 "box" 的元素
      ele.style.transition = "transform .5s ease-in 1s"
      let deg = i % 2 ? 90 : 0
      ele.style.transform = `rotate(${deg}deg)`
      i ++
    }

animation的用法:

  • animation是个复合属性,是7个属性的缩写。 animation-name, animation-durationanimation-timing-functionanimation-delayanimation-iteration-countanimation-directionanimation-play-state

    • 上面7个属性中难点是 animation-name的定义。 animation-name要用 @keyframes方法来定义。具体定义方法是:

      @keyframes disapper{
        from{opacity: 1;}
        to{opacity:0;}
      }
      // 复杂的可以不用from,to,直接用百分号
      @keyframes dis{
        from{transform: translate(0,0)}
        20%{transform: translate(20,20)}
        to{transform: translate(100,20)}
      }
      // from 等价于 0%, to 等价于 100%
    • 在使用animation之前,先定义 animation-name,然后在按照这几个属性的顺序,给元素加animation属。例如要实现一个三角形先旋转90度,然后右移100px,然后下移100px,然后左移100px,左移的同时,渐渐消失。

      • 旋转: transform的rotate; 右移,下移,左移: transform的translate; 下移: transform的translate; 消失: opacity
      •   .box{
            width: 0;
            height: 0;
            border-top: 0;
            border-left: 50px solid transparent;
            border-right: 50px solid transparent;
            border-bottom: 50px solid #28b9c4;
            animation: moveAndDisapper 10s ease-out 0s 3;  // 踩过了一个坑,当第四个参数animation-delay要填,且是0的时候,单位要带上,要写0s。否则浏览器无法识别
            -webkit-animation: moveAndDisapper 10s ease-out 0s 3;
          }
          @keyframes moveAndDisapper {
            0%{transform: rotate(0deg)}
            20%{transform: rotate(90deg) translate(0, 0)}
            40%{transform: rotate(90deg) translate(0, -100px);opacity: 1;}
            60%{transform: rotate(90deg) translate(100px, -100px); opacity: .3}
            80%{transform: rotate(90deg) translate(100px, 0px); opacity: .3}
            90%{ transform: rotate(90deg) translate(0, 0);opacity: 1}
            100%{ transform: rotate(0deg) translate(0, 0);opacity: 1}
          }
          @-webkit-keyframes moveAndDisapper{
            // 代码和@keyframes moveAndDisapper 相同
          }

part 2:

  1. 如何实现一个div水平、垂直居中?扩展一下float的用法和flex的用法。

    前置条件:外层div.parent里面又放了一个div.child

    • div水平居中的几种方法
    // 方法一:parent不做处理, child设margin
    .child{
        margin: 0 auto;
    }
    // 方法二:parent设text-align:center, child设display:inline-block
    .parent{
        text-align: center;
    }
    .child{
        display: inline-block;
    }
    // 方法三: 用float和relative,原理是float后,元素的宽高是子元素的宽高;relative时,可设置left和right属性
    // 在parent和child中间再加一个between标签,between的宽高和child相同,bewteen带着child左移50%(基于parent),child然后右移 50%(基于between),最后child就居中了
    .between{
      position: relative;
      left: 50%;
      float: left;
    }
    .child{
      width: 50px;
      height: 50px;
      position: relative;
      right: 50%;
    }
    • div垂直居中的几种方法

      思路:top 50%,然后向上移动自身高度的50%

    // 已经知道大盒子的高度和宽度时, 用position和margin来计算
    .parent{
        position: relative;
    }
    .child{
        position:absolute;
        margin: 75px 0;
    }
    // 已知小盒子的宽度,用position和transform,
    .parent{
        position: relative;
    }
    .child{
        position: absolute;
        top: 50%;
        transform: translate(0%, -50%);
    }
    // flex布局
    .parent{
        display: flex;
        align-items: center;
    }
    // table-cell布局
    .parent{
        display:table;
    }
    .between{
        display:table-cell;
        vertical-align:middle;
    }
    • div垂直水平居中

      方法一:

      思路: 内层盒子相对外层盒子,top 50%, left 50%,然后translate移动自身高宽的 50%

    .parent{
        position: relative;
    }
    .child{
        position:absolute;
        top:50%;
        left: 50%;
        transform: translate(-50%, -50%)
    }

​ 方法二:(推荐,不知道高宽的时候也可以用)

​ 思路:内层盒子相对外层盒子,left,right,top,bottom都是0,margin: auto

.parent{
    position: relative;
}
.child{
    position: absolute;
    top: 0;
    left: 0;
    bottom:0;
    right:0;
    margin:auto;
}

​ 方法三:

​ 思路: 知道高宽的时候,通过margin的设置,来达到居中

.parent{
    position: relative;
}
.child{
    position: absolute;
    top: 50%;
    left: 50%;
    margin-top: -25px;
    margin-left: -25px;
}

方法四:

思路: 通过flex布局,横轴和纵轴都居中

.parent{
    display: flex;
    justify-content: center;
    align-items: center;
}
  1. 用flex如何实现两个盒子,左右居中,并且宽度自动占满50%?

    思路是利用 flex属性,来让子盒子平分宽度

    html设置:

    <div class="box">
        <div class="item1">1</div>
        <div class="item2">2</div>
        <div class="item3">2</div>
    </div>

    css设置: 父元素设置display:flex 子元素设置flex: 1

      .box{
        width: 400px;
        height: 400px;
        display: flex;
        background-color: #e0e012;
      }
      .box > div{
        height: 100px;
        flex: 1;
      }

    flex设为整数,或者 flex设为auto均生效。

  2. 写一个方法,将传入的字符串的每个字符后面都加上空格?

    function getStr(str){
      let arr = str.split("")
      let newStr = arr.join(" ")
      console.log(newStr);
    }
    
    function getStr(separator){
        let args = [...arguments]
        return args.join(separator)
    }
  3. 写一个方法,打印出传入的值。补充arguments的用法。

    function logStr(){
      console.log(...arguments);
    }

    补充一下 arguments的用法。

    function logStr(){
      console.log(arguments[0] === arr);
      console.log(...arguments);
    }
    
    let arr = ["good"]
    let name = "cc"
    logStr(arr, name)  // true  ["good"] "cc"

    arguments[0] === arr可得, argument的内容和参数是可以一一对应上的,不管是复杂类型的变量 【数组、对象, Symbol等】,还是普通类型变量

    mdn文档笔记:

    • arguments是类数组,可以运用index访问各个元素,也有length,但是没有数组的方法forEach
    • 用扩展运算符 ...或者 Array.from()可以把 arguments转化为真正的数组

joychenke
47 声望3 粉丝

业精于勤荒于嬉。加油ヾ(◍°∇°◍)ノ゙