以下是一些前端面试题:
一、HTML/CSS部分
- 如何实现一个自适应的图片容器,在不同屏幕尺寸下图片按比例缩放且不失真?
- 答案:
- 方法一:使用
max - width
和height: auto
属性。 - 在CSS中为图片设置
max - width: 100%; height: auto;
,这样图片会根据其容器的大小按比例缩放,并且不会出现失真的情况。 - 方法二:使用
object - fit
属性(适用于现代浏览器)。 - 如果希望图片填充整个容器并且保持比例,可以设置
object - fit: cover;
;如果希望图片完整显示在容器内并且可能留白,可以设置object - fit: contain;
。
- CSS中
display: none
和visibility: hidden
有什么区别?
- 答案:
-
display: none
: - 元素完全从页面布局中移除,不占据任何空间,其后的元素会占据该元素原本的空间位置。
- 例如,当隐藏一个导航菜单时,如果使用
display: none
,菜单所在的空间将空出,后面的内容会向上移动。 -
visibility: hidden
: - 元素仍然占据页面布局中的空间,只是不可见。
- 例如,当隐藏一个装饰性元素时,如果使用
visibility: hidden
,它所在的空间仍然保留,后面的元素不会移动。
- 如何使用CSS实现一个简单的动画效果(如淡入淡出)?
- 答案:
- 可以使用CSS的
transition
属性或者@keyframes
规则结合animation
属性来实现淡入淡出效果。 - 使用
transition
实现淡入淡出(以一个div
元素为例): - HTML:
<div class="fade - element"></div>
- CSS:
.fade - element {
opacity: 0;
transition: opacity 1s ease - in - out;
}
.fade - element.show {
opacity: 1;
}
- 然后通过JavaScript或其他方式给
div
元素添加或移除show
类来触发淡入淡出效果。 - 使用
@keyframes
和animation
实现淡入淡出: - HTML同上。
- CSS:
@keyframes fade - in - out {
0% {
opacity: 0;
}
50% {
opacity: 1;
}
100% {
opacity: 0;
}
}
.fade - element {
animation: fade - in - out 2s infinite;
}
二、JavaScript部分
- JavaScript中的
this
关键字是如何工作的?请举例说明不同情况下this
的指向。
- 答案:
- 在全局作用域中,
this
指向全局对象(在浏览器中是window
对象)。 - 例如,在全局脚本中直接定义一个函数
function foo() { console.log(this); }
,调用foo()
时,this
指向window
。 - 在函数内部,
this
的值取决于函数的调用方式。 - 如果是作为普通函数调用,
this
指向全局对象(严格模式下为undefined
)。 - 如果是作为对象的方法调用,
this
指向该对象。 - 例如:
let obj = {
name: 'John',
sayName: function () {
console.log(this.name);
}
};
obj.sayName(); // this指向obj
- 在构造函数中,
this
指向新创建的对象实例。 - 使用
call
、apply
、bind
方法可以显式地设置this
的值。
- 如何实现一个简单的JavaScript模块模式?请举例说明其优点。
- 答案:
- 模块模式的实现:
- 可以使用立即执行函数表达式(IIFE)来创建模块。
- 例如:
let module = (function () {
let privateVariable = 'This is private';
function privateFunction() {
console.log(privateVariable);
}
return {
publicMethod: function () {
privateFunction();
}
};
})();
module.publicMethod();
- 优点:
- 数据封装,将变量和函数封装在模块内部,避免了全局命名空间的污染。
- 可以定义私有变量和函数,只暴露必要的公共接口,提高代码的安全性和可维护性。
- 请解释JavaScript中的异步编程概念,并且说明
Promise
相对于回调函数的优点。
-
答案:
-
异步编程是指在执行耗时操作(如网络请求、文件读取等)时不阻塞后续代码的执行。
-
Promise
相对于回调函数的优点: -
避免回调地狱(Callback Hell),当有多个嵌套的回调函数时,代码结构会变得非常复杂难读,而
Promise
可以通过链式调用的方式使代码结构更加清晰。 -
更好的错误处理机制,
Promise
可以使用.catch()
方法统一处理错误,而回调函数需要在每个回调中单独处理错误。
三、框架相关(以Vue.js为例)
- Vue.js中的计算属性(computed properties)和方法(methods)有什么区别?
- 答案:
- 计算属性是基于它们的依赖进行缓存的。只有当依赖发生变化时,计算属性才会重新计算。
- 例如,在一个Vue组件中,如果有一个计算属性
fullName
依赖于firstName
和lastName
,当firstName
或lastName
改变时,fullName
才会重新计算。 - 方法则是在每次组件重新渲染时都会被调用,不管依赖是否改变。
- 例如,在模板中直接调用一个方法来获取某个值,每次渲染都会执行这个方法。
- 如何在Vue.js中实现组件间的数据传递(除了
props
和$emit
之外)?
- 答案:
- 使用Vuex进行状态管理。将共享的数据存储在Vuex的store中,组件通过
mapState
、mapGetters
等辅助函数来获取数据,通过mapActions
、mapMutations
来修改数据。 - 使用
provide
和inject
(在Vue 3中仍然支持这种方式并且更加灵活),祖先组件可以提供数据,后代组件可以注入这些数据,不需要一层一层地传递。
- Vue.js中的
v - if
和v - show
有什么区别?
-
答案:
-
v - if
是“真正”的条件渲染,它会根据表达式的值在DOM中添加或移除元素。如果初始条件为假,则元素不会被渲染到DOM中;当条件变为真时,才会被渲染。 -
v - show
只是切换元素的display
属性,元素始终存在于DOM中,根据表达式的值在display: none
和默认的display
值之间切换。
四、性能优化
- 如何优化JavaScript的执行效率?
- 答案:
- 避免全局查找,在函数内部使用局部变量来缓存全局变量或对象属性的值。
- 减少DOM操作,尽量将多次DOM操作合并为一次,例如使用
DocumentFragment
来进行批量DOM更新。 - 对于循环操作,优化循环条件和循环体,避免在循环内部进行复杂的计算。
- 使用事件委托来减少事件处理程序的数量,例如将多个子元素的事件处理委托给它们的父元素。