上周去面了两家公司,part1是第一家公司的部分试题,part2是第二家公司的部分试题
Part 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对象
调用
-
下面的函数输出什么?
含 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 -
Promise
的then
方法是当前脚本的所有同步任务执行完了之后,也就是本轮事件循环
结束时执行,打印 finished - Promise构造函数的两个参数分别是 resolve和reject,resolve会将promise实例的状态置为fulfilled(完成),然后代码就不会往下执行。接着代码就会走到then方法中,then方法中的参数,就是resolve的结果,当resolve中参数一个非promise时,res就是这个参数本身 打印a resolved
-
-
css3的几个属性 translate,transform,transition,animation。拓展:几个css3特效的用法。
这几个属性的区别 区别说明的网站
translate
用法:-
translate
是transform
的一个属性。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-property
,transition-duration
,transition-timing-function
,transition-delay
。分别表示:过渡效果的css属性名称、完成过渡效果需要的秒或毫秒、速度效果的速度曲线、过渡效果何时开始。transition
属性是这四个属性是顺序往后排。第一个transition-property
和transition-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-duration
,animation-timing-function
,animation-delay
,animation-iteration-count
,animation-direction
,animation-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:
-
如何实现一个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;
}
-
用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
均生效。 -
写一个方法,将传入的字符串的每个字符后面都加上空格?
function getStr(str){ let arr = str.split("") let newStr = arr.join(" ") console.log(newStr); } function getStr(separator){ let args = [...arguments] return args.join(separator) }
-
写一个方法,打印出传入的值。补充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
转化为真正的数组
-
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。