该篇文章为一句话回答面试题的答案,想看更详细的面试题解析请看这篇>《前端面试题》
JS
let和var的区别
let的作用域只在所在代码块,在let申明变量之前,调用会导致引用错误,var则是为undefined。
const是否真的不能改变?
不一定。const的不可改变是指变量的绑定不可变,对于const的值为基本数据类型时,确实不可改变;但对于对象(包括数组和函数)修改其内部的属性或方法是可以的,因为这并不会改变变量的绑定,它始终指向同一个内存地址。
变量提升
在JS中,变量和函数的声明会被提升到最顶部执行,但变量提升不会改变赋值的位置,只是将声明提前,而函数会完全提升。
类型检测
Object.prototype.toString.call() 最准确(包括
null
和undefined
),其他:typeof、instanceof、constructor都有缺点
原型和原型链
- 原型:每个对象都有一个原型 prototype,原型为当前对象提供默认的属性和方法。
- 原型链:实例与原型之间的链条 __proto__,当访问一个对象的属性或方法时,如果该对象没有这个属性或方法,JavaScript 会沿着原型链向上查找。
- 原型链的终点:所有原型的原型都是Object.prototype,而Object.prototype的原型是null,null就是所有原型链的终点。
继承
ES6 使用extends关键字对Class类继承,ES6之前:构造函数、原型链、构造+原型链、原型式、寄生式、原型+寄生。
使用new关键字时发生了什么?
1、创建空对象
2、设置原型
3、绑定this并执行构造函数
4、返回对象
事件循环
JS分为同步和异步任务。同步任务在主线程上执行,一旦执行栈中的所有同步任务执行完毕,系统就会读取任务队列(可以有多个),将可运行的异步任务添加到执行栈中,开始执行。
事件队列
分为微任务、宏任务,微任务一般比宏任务先执行,并且微任务队列只有一个。
宏任务:setTimeout、setInterval,点击和键盘事件......
微任务:Promise、process.nextTick.......
防抖和节流
都是为了阻止操作高频触发,从而浪费性能。防抖执行最后一次,节流执行第一次。
防抖:搜索联想、窗口调整;节流:鼠标连点、滚动加载。
Promise
Promise
对象代表一个异步操作,只有三种状态,进行中、已成功、已失败。异步操作的结果决定状态,当状态从pending
变为fulfilled/
rejected
,状态就不会再改变,称为 resolved。
Promise对象有哪些静态方法
.all()、.resolve()、.reject()、.race()
Promise.all()如果传入的数组不是Promise会怎么样
Promise.all 会将 非Promise 的对象视为已经 resolve 的 Promise 对象,并且值就是这些非 Promise 对象本身。
Promise.all()和Promise.race()的区别?
用法一样,但.all()会等待所有Promise状态完成,而.race()则不同,只要任意一个Promise状态改变,就会改变状态,并返回Promise的返回值给回调函数。
async/await
本质还是Promise,有多个连续的异步操作时,会比Promise更简洁易读。
async :申明方法是异步的;await:等待异步方法执行完成;返回值是 Promise 对象。
process.nextTick() 和setImmediate()
被设置的回调函数都是在下一次 Tick 时被调用,process.nextTick()优先级更高。
闭包
闭包就是函数内嵌套函数,使函数外可以读取到函数内部的变量,未释放前变量会一直占用内存。用途:模块化、防抖、节流、封装函数延迟执行。
箭头函数和普通函数的区别
箭头函数更简洁,没有自己的this,this指向定义时所在作用域的this,且不会改变。
不可以当作构造函数,不可以使用new命令,不可以使用arguments,不可以使用yield命令。
this指向
全局作用域和普通函数的this指向全局对象;当函数作为对象的一个方法被调用时,this 指向该对象;当使用 new 关键字调用函数时,this 指向新创建的对象;箭头函数没有自己的 this ,它会捕获外部作用域中的 this 值;在事件中,this 通常指向触发事件的 DOM 元素。
在 严格模式 下(使用
全局作用域
非严格模式下指向全局对象window (浏览器) 或 global (Node.js)
普通函数调用
非严格模式下指向全局对象window (浏览器) 或 global (Node.js)
对象方法调用
作为对象的一个方法被调用时,指向调用该对象。
构造函数调用
使用 new 关键字调用函数时,指向新创建的对象。
箭头函数
没有自己的 this,会捕获外部作用域中的 this 值。
事件
指向触发事件的 DOM 元素
"use strict";
指令),this
的值有所不同。在全局作用域或普通函数调用中,this
的值是undefined
。
显式绑定 this
可以使用 .call(), .apply(), 和 .bind() 方法来显式地设置 this 的值。
call
() 和 apply
() 以及 bind
()的区别
call()
:立即调用函数,并设置this
值,接受多个参数。apply()
:接收参数不同,为数组。bind()
:不会调用函数而是创建一个新函数,其余和call一样。
call()、
apply()、
bind()的
用途
call()
和 apply()
:通常用于需要立即调用一个函数,并且需要显式地设置this
值的情况。bind()
:通常用于创建新的函数版本,这些函数在被调用时具有固定的this
值,常用于事件处理程序和回调函数中。
JS的作用域有哪些?
作用域可分为两种主要类型全局和局部,而局部作用域可分为词法、块级。
闭包是一种特殊的词法作用域现象,它允许一个函数访问其外部函数的变量,即使外部函数已经执行完毕。闭包可以用来创建私有变量和方法。
全局作用域
最外层的作用域,其中定义的变量在整个脚本中都是可访问的。
局部作用域
在函数内部定义的作用域,其中定义的变量只能在其所在函数内部被访问。
词法作用域
变量的作用域由它们在源代码中的位置决定。
块级作用域
由 {} 定义的作用域,其中定义的变量只能在该块内被访问。
闭包
允许函数访问其外部函数的变量,即使外部函数已经执行完毕。
什么是作用域链?
是一个链接列表,每个链接都代表一个作用域,从当前作用域开始,包含了所有外部作用域直到全局作用域。
作用域链的工作原理
当函数中访问一个变量时,JavaScript 引擎会沿着作用域链查找该变量。首先检查当前作用域,如果没有找到,则继续在外部作用域中查找,一直查找到全局作用域,如果在作用域链中找不到该变量,则抛出 ReferenceError。
数组去重的方法?
ES6的Set、循环+判断:Array.filter() + indexOf() / Array.includes()
Promise 面试题 以下代码的执行结果是?
const promise = new Promise((resolve, reject) => {
console.log(1)
resolve()
console.log(2)
})
promise.then(() => {
console.log(3)
})
console.log(4)
答案:选中👉1,2,4,3
解释:以上考察的是关于promise的原理,promise的构造函数是同步执行的,当new Promise的一瞬间,1,2 就立刻被执行,而 .then方法是异步执行的,当执行完1和2之后,会执行输出4,最后执行输出3
数组扁平化使用场景
快速获取/过滤嵌套数组中的某个值
数组求和
const arrSum = (arr) => {
const temp = arr.reduce((pre, now) => {
return pre+now
},0)
return temp
}
求数组的最大值/最小值?
Math.max();
Math.min();
问:以下代码的打印值?
class Foo {
constructor(arr) {
this.arr = arr
}
bar(n) {
return this.arr.slice(0,n);
}
}
var f = new Foo([0,1,2,3]);
console.log(f.bar(1));
console.log(f.bar(2).splice(1,1));
console.log(f.arr);
选中看答案👉:[0]、[1]、[0, 1, 2, 3]
Promise执行顺序
new Promise((resolve,reject)=>{
reject(1);
console.log(2);
resolve(3);
console.log(4);
})
.then((res)=>{
console.log('reject')
}).catch((res)=>{
console.log('rej1')
})
try{
new Promise((resolve,reject)=>{
throw "error"
}).then((res)=>{
console.log(res)
}).catch((res)=>{
console.log('rej2')
})
} catch(err) {
console.log(err);
}
选中看答案👉:2、4、rej1、rej2
解构赋值
let a = 1; let b = 2; 如果在不声明第三个变量的前提下,使a=2, b=1?
答案:选中👉[a, b] = [b, a]
为什么要使用组件?
方便维护、方便复用、提高开发效率
在组件的设计中,需要考虑什么?
可扩展性强、功能单一、便于复用,适用程度高
前端性能优化:
主要分为两部分:
1、资源优化,合并、压缩、CDN、缓存、异步加载模块。
2、代码优化,减少代码冗余、使用性能更好的API、减少重绘回流。
还可以通过SSR、SSG提升首屏加载速度。
虚拟dom为什么会快?
虚拟 dom 相当于在 js 和真实 dom 中间加了一个缓存,利用 dom diff 算法计算出差异,只更新差异点,从而提高性能。
loader 和 plugin的区别?说几个Webpack常用 loader 和 plugin:
loader处理语法、plugin帮助资源文件打包优化
babel-loader、vue-loader、 file-loader、url-loader、eslint-loader、cache-loader、css-loader......
uglify-webpack-plugin(压缩js)、optimize-css-assets-webpack-plugin(压缩css)、html-webpack-plugin、webpack-bundle-analyzer(打包文件体积可视化)......
Vue面试题
想要详细的解答可以看这篇->Vue面试题
vue几种常用的指
v-for 、 v-if 、v-show、v-bind、v-on
v-if 和 v-show 区别
v-if按照条件是否渲染,v-show是display的block或none,会一直存在于DOM。v-if是动态创建和销毁元素,因此对性能的影响较大,不适合频繁切换条件。
css只在当前组件起作用
在style标签中写入scoped即可 例如:<style scoped></style>
vue常用的修饰符
.trim、.once、.stop、.self、.capture、
v-once 指令的使用场景有哪些?
v-once 指令用于只渲染元素或组件一次,适用于那些不需要在数据变化时更新的静态内容,可以用来优化性能,避免不必要的重新渲染。
v-for和v-if 可以在同一个标签内使用吗?有什么问题?
可以但不推荐,因为优先级不同。
Vue3.0
v-if 比 v-for 的优先级更高,这意味着 v-if 的条件将无法访问到 v-for 作用域内定义的变量别名。
Vue2.0
v-for的优先级比v-if高,会先循环,再判断,造成性能浪费。
key 值的作用?
key
值主要用于给每个节点的唯一标识,Vue在更新时,它会基于key
值来跟踪每个节点,从而重用和重新排序现有元素,而不是销毁并重新创建它们。使用key
值可以提高渲染性能,尤其是在处理大型列表或频繁更新的列表。
计算属性和watch的区别
计算属性:定义一个属性,这个属性的值是基于其他属性值的计算结果,会因为其他属性值变化而更新。
Watch:可以监听任何 Vue 实例上的数据变化,并执行相应的函数。
为什么要使用 ref?
当你在模板中使用了一个 ref,然后改变了这个 ref 的值时,Vue 会自动检测到这个变化,并且相应地更新 DOM。
什么是refs,有什么用?
refs
是一个特殊的属性,用于引用 Vue 实例中的子组件或 DOM 元素。通过在子组件或 DOM 元素上添加ref
属性,你可以在 Vue 实例中通过$refs
对象来访问这些引用。
Vue 中的 nextTick 是做什么的?
nextTick 是一个 Vue 实例的方法,用于在 DOM 更新完成后执行回调函数,如果在数据更改后需要立即获取新的 DOM 元素位置时,可以使用 nextTick。
什么是slot(插槽)?
在某些场景中,我们可能想要为子组件传递一些模板片段,让子组件在它们的组件中渲染这些片段,这个时候我们就可以使用slot。
Vue组件间通信
props/$emit、状态管理(Vuex/Pinia)、$refs、插槽slot
Vue 3.x 中有哪些新特性?
Composition API:一种新的API,用于更灵活地组织和重用组件逻辑。
Teleport:允许将一个元素“传送”到 DOM 树中的另一个位置。
Suspense:用于处理异步组件的加载状态。
Fragment:允许组件渲染多个根元素。
Vue实现数据绑定的原理
- Vue2 基于 Object.defineProperty 方法重定义对象的 getter 与 setter。
- Vue3 基于 Proxy 代理对象,拦截对象属性的访问与赋值过程。
Vue2如何监听数组变化
Composition API有什么好处?
写法更简洁灵活,和TypeScript更配。
如何在 Vue 中实现服务端渲染 (SSR)?
- 使用 Vue.js 官方支持的 SSR 解决方案,例如 Nuxt.js。
- 或者手动设置服务器端渲染流程,使用 vue-server-renderer 库。
- 服务器端渲染可以提高首屏加载速度和搜索引擎优化(SEO)。
React面试题
类组件和函数组件的区别是什么?
- 类组件:功能完善,可以使用其他特性,如状态和生命周期钩子,有this。
- 函数组件:语法更短、更简单,只能接收props渲染到页面,且props不会改变,无state,没有this,不能使用生命周期钩子。(可用hooks解决部分问题)
Hooks是什么?
Hooks是 React 16.8 中的新添加内容。它们允许在不编写类的情况下使用state和其他 React 特性,从而使得函数组件更加强大和灵活。
常用的Hook
useState、useEffect、useMemo、useCallback、useRef