一、写在前面的话
一只慢慢慢慢变强的前端菜鸟,下面都是自己在面试和学习中的问题的总结,帮助自己巩固知识点的同时也希望能帮助到你们。
二、面试题
这里我会总结出遇到的面试题和一部分学习中遇到的问题,会结合文档和大佬们的博客进行解析,若大家在看到的时候发现错误和不当之处请多多指教。
2.1 数组去重
我的思路是借助对象属性的唯一性来去除重复元素,通过循环将数组中的元素作为对象的key值,相同属性会重复赋值,但是属性不会增加,最后通过遍历对象的属性就能得到唯一元素了。
Array.prototype.unique = function () {
let res = []
let temp = {}
let length = this.length
for (let i = 0; i < length; i++) {
if (!temp[this[i]]) {
temp[this[i]] = true
res.push(this[i])
} else if (res.indexOf(this[i]) === -1) {
res.push(this[i])
}
}
return res
}
这里需要注意的是通过[]来获取对象属性值的时候,[]内必须是计算结果为字符串的表达式,因此'1'和1会被认为是相同元素,所以我们需要通过数组的indexOf方法确定数据类型为字符串的元素在数组中是否存在,不存在就需要往数组中push该元素。
2.2 flex是什么以及主要属性
flex指的是弹性盒子布局,当我们给元素设置display:flex属性的时候就可以为该元素的子元素开启flex布局,这个父元素称之为flex-container,子元素们称之为flex-items。
1.应用在flex-container上的主要属性有:
flex-direction决定主轴的方向,有四个取值:row、row-reverse、column、column-reversejustify-content决定flex-item在主轴的对齐方式,有六个取值:flex-start(与主轴起点对齐)、flex-end(与主轴终点对齐)、center(居中对齐)、space-between(flex-items彼此距离相等且与主轴起点和终点对齐)、space-evenly(flex-items彼此距离相等且与主轴起点和终点等距)、space-around(flex-items与起点和终点的距离是flex-items彼此距离的一半)flex-wrap决定flex-items是否多行排布,有三个取值:normal(单行,默认值)、wrap(多行)、wrap-reverse(多行,反向)align-items决定单行flex-items在交叉轴的对齐方式,有五个取值:flex-start(与交叉轴起点对齐)、flex-end(与交叉轴终点对齐)、center(居中对齐)、stretch(若flex-item没有设置高度或者为auto则拉伸至整个container的高度),baseline(基准线对齐)align-content决定多行flex-items在交叉轴的对齐方式,取值参考justify-content,对单行flex-items不起作用
2.应用在flex-items上的主要属性:
order决定该flex-item的排列顺序,order值越小越靠前,默认值是0可为负align-self决定设置了该属性的flex-item的排布顺序,用来覆盖align-items的属性值,取值通align-items的取值flex-grow决定了该flex-item如何拓展,只有主轴方向有剩余空间才生效flex-shrink决定了该flex-item如何收缩,只有主轴方向flex-items的宽度超出空间才生效flex-basic决定了该flex-item在主轴的宽度
2.3 函数题1
var a = function b() {
console.log(a == b);
};
a(); // true
b(); // Error: b is not defined
个人感觉从结果上分析,具名的函数表达式,函数名变成了类似于函数内部的局部变量,只有内部才能访问
var test = function tool(){
console.log(tool)
}
test() //[Function: tool]
console.log(tool) //ReferenceError: tool is not defined
2.4 css实现div旋转
这里可以通过css的animation属性和关键帧以及transform属性完成 首先定义关键帧的名称,关键帧的动画详情
@keyframes rotate {
0% {
transform: rotate(0deg);
}
50% {
transform: rotate(180deg);
}
100% {
transform: rotate(360deg);
}
}
然后定义animation属性
animation: rotate 3s infinite;
2.5 函数题2
var obj = {"name":"1"};
(function(obj){
obj = {"name":"3"};
})(obj);
console.log(obj)
// { name: "1" }
这里主要是以下知识点:
- 在js中,函数的参数是无论类型都是按照值进行传递的,也就是说将函数外部的值复制给函数内部的参数。
- 在js中,那么基本类型的值就是简单的复制,而引用类型的值复制的就是保存这个引用类型的地址的指针。
- js中可以把函数参数理解为局部变量
所以上面的可以理解为:
(function(obj){
obj = 实参对象的指针,指向原对象
//对obj重新赋值,obj的指针由原对象更改为新对象,且这个新对象在函数执行完被销毁
obj = {"name":"3"};
})(obj);
console.log(obj) // 而全局变量obj一直拥有原对象指针
对比来讲的话:
var obj = {"name":"1"};
(function(obj){
obj.name = "3";
})(obj);
console.log(obj)
// {"name":"3"}
这里与上面的差别就是obj的指针没有变化,还是指向原对象因此改变属性值会改变原对象的值,而全局变量obj也拥有的是原对象的指针,因此打印的对象就发生了变化。
2.6 行内、块级、行内块级元素的特点
- 行内元素:默认宽度为内容宽度,不可设置宽高,同行显示(
img、input等元素除外,它们可以设置宽高可以看作行内块级元素) - 块级元素:默认宽度为父元素的宽度,可以设置宽高,换行显示
- 行内块级元素:集成了前两者的部分属性,默认宽度为内容宽度,同行显示,可以设置宽高
2.7 js和css加载会造成阻塞吗?
分情况,css文件的加载不会阻塞dom的解析,但是会阻塞dom的渲染(等到加载完才开始渲染),会阻塞js代码的执行,而js加载是会阻塞dom的解析,若不想阻塞可以加上async或者defer标签让js异步加载
2.8 写一个函数实现以下效果:
1
11
111
1111
11111
function print(n) {
let res = 0
for (let i = 0; i < n; i++) {
res += 10 ** i
console.log(res)
}
}
print(5)
js中幂运算符号为两个*符号