目录
1.不使用promise怎么实现一个异步编程?
2.this的指向有哪些?
3.Ref和reactive响应式的区别?
4.首屏加载优化。如何处理?
5.axios封装?
6.css为什么使用预处理?
7.从1000-9999里面取出AAAA这种数字?
8.销毁的生命周期在什么时候使用?
9.怎么做配置代理?
10.怎么改变this指向,他们有什么不同?
11.分包和懒加载有什么不同?
12.虚拟dom和真实dom怎么做对比?
13.axios和fetch区别?
14.宏任务和微任务?
15.webpack打包流程?
16.什么是垃圾回收机制?
17.Promise 的方法有哪些,分别有什么作用?
18.说说你对 TypeScript 的理解?与 JavaScript 的区别?
19.什么是事件循环机制?
20.工厂模式和发布订阅者模式的区别?
1.不使用promise怎么实现一个异步编程?
①回调函数:将一个函数作为另一个函数的参数传递,当第一个函数完成时,第二个函数将被调用。 最常用的异步编程方式
function fetchData(callback) {
setTimeout(() => {
const data = { message: "Hello, world!" };
callback(data);
}, 1000);
}
fetchData(data => {
console.log(data.message);
});
②Async/Await:ES2017 引入了 async/await,使得异步编程更加简单易读。async 函数返回一个 Promise 对象,可以使用 await 关键字来等待异步操作的结果。
function fetchData() {
return new Promise(resolve => {
setTimeout(() => {
const data = { message: "Hello, world!" };
resolve(data);
}, 1000);
});
}
async function printData() {
const data = await fetchData();
console.log(data.message);
}
printData();
③事件监听器:使用事件监听器来处理异步操作的结果。例如,使用 XMLHttpRequest 对象时,可以监听 load 事件以处理响应数据。
const request = new XMLHttpRequest();
request.open("GET", "https://api.example.com/data");
request.addEventListener("load", () => {
const data = JSON.parse(request.responseText);
console.log(data.message);
});
request.send();
④Generator 函数:使用 Generator 函数可以通过 yield 关键字来暂停和恢复函数的执行。可以将异步操作封装在 Generator 函数中,然后使用 next() 方法来控制函数的执行。
function* fetchData() {
const data = yield new Promise(resolve => {
setTimeout(() => {
const data = { message: "Hello, world!" };
resolve(data);
}, 1000);
});
console.log(data.message);
}
const generator = fetchData();
const promise = generator.next().value;
promise.then(data => generator.next(data));
2.this的指向有哪些?
①作为函数调用,非严格模式下,this指向window,严格模式下,this指向undefined;
②作为某对象的方法调用,this通常指向调用的对象。
③ 使用apply、call、bind 可以绑定this的指向。
④ 在构造函数中,this指向新创建的对象
⑤ 箭头函数没有单独的this值,this在箭头函数创建时确定,它与声明所在的上下文相同。
3.ref和reactive响应式的区别?
①ref多用来定义基本数据类型,而 reactive 只能用来定义对象数组类型;
②ref操作数据需要 .value ,reactive 操作数据不需要 .value。
4.首屏加载优化。如何处理?
①压缩文件体积;
②减少请求次数。
5.axios封装?
//axios封装
import axios from 'axios';
// 环境的切换
if (process.env.NODE_ENV == 'development') {
axios.defaults.baseURL = '';
} else if (process.env.NODE_ENV == 'production') {
axios.defaults.baseURL = '';
}
// 请求超时时间
axios.defaults.timeout = 10000;
// 请求拦截器
axios.interceptors.request.use((config) => {
//判断是否存在token
let token = localStorage.getItem('_token');
token && (config.headers[""] = token);
return config;
},(error) => {
return Promise.error(error);
});
// 响应拦截器
axios.interceptors.response.use((response) => {
if (response.status === 200) {
return Promise.resolve(response);
} else {
return Promise.reject(response);
}
},(error) => { // 服务器状态码不是200的情况
if (error.response.status) {
switch (error.response.status) {
// 401: 未登录
// 未登录则跳转登录页面,并携带当前页面的路径
// 在登录成功后返回当前页面,这一步需要在登录页操作。
case 401:
break;
// 403 token过期
// 登录过期对用户进行提示
// 清除本地token和清空vuex中token对象
// 跳转登录页面
case 403:
break;
// 404请求不存在
case 404:
break;
// 其他错误,直接抛出错误提示
default:
return Promise.reject(error.response);
}
}
);
// get方法
export function get(url, params){
return new Promise((resolve, reject) =>{
axios.get(url, {
params: params
})
.then(res => {
resolve(res.data);
})
.catch(err => {
reject(err.data)
})
});
}
//post方法
export function post(url, params) {
return new Promise((resolve, reject) => {
axios.post(url, QS.stringify(params))
.then(res => {
resolve(res.data);
})
.catch(err => {
reject(err.data)
})
});
}
6.css为什么使用预处理?
①简化代码:预处理器可以通过变量、函数和混合(mixins)等功能使CSS代码更简洁。这样可以减少代码的重复,提高代码的可读性和可维护性。
②提高效率:预处理器可以将CSS代码分解成多个模块,可以分别编辑和测试,最后再合并成一个CSS文件。这样可以提高开发效率,特别是在大型项目中。
③增强功能:预处理器可以扩展CSS的功能,如嵌套规则、条件语句等功能,这样可以更快捷地实现一些复杂的CSS效果。
④避免错误:预处理器可以通过变量和函数来避免出错。例如,当需要修改一个颜色时,只需要修改变量的值,所有的使用该颜色的样式都会自动更新,从而避免了修改错误的风险。
CSS预处理器可以提高CSS的可维护性、可读性和效率。常用的CSS预处理器有Sass、Less和Stylus等。
7.从1000-9999里面取出AAAA这种数字?
8.销毁的生命周期在什么时候使用?
销毁生命周期一般用于释放不再需要的资源,避免内存泄漏或占用过多内存。
9.怎么做配置代理?
10.怎么改变this指向,他们有什么不同?
call()、apply() 、bind()
区别:①call、apply是立即执行,而bind是返回一个改变上下文的函数副本,原来函数不发生变化。
②apply方法接收两个参数,一个是函数运行的作用域,另一个是参数数组;call方法与apply方法不同之处在于传递给函数的参数必须列举出来。bind参数方式同call相同。
11.分包和懒加载有什么不同?
①分包是将一个大型的应用程序划分为多个小模块,每个模块可以独立地进行加载和更新。当用户访问应用程序时,只需要加载当前所需的模块,而不是一次性加载整个应用程序。而懒加载是将网页中的资源(如图片、视频等)延迟加载,直到用户需要访问它们时再进行加载。这样可以减少页面的初始加载时间,提高用户体验。
②分包是针对整个应用程序的优化,而懒加载则是针对单个资源的优化。
③分包可以减少首次加载时间,但不一定能降低页面的渲染时间;懒加载可以降低页面的渲染时间,但不一定能减少首次加载时间。
12.虚拟dom和真实dom怎么做对比?
①虚拟DOM不会进⾏回流和重绘;真实DOM在频繁操作时引发的回流重绘导致性能很低;
②虚拟DOM频繁修改,然后⼀次性对⽐差异并修改真实DOM,最后依次回流重绘,减少了真实DOM中多次回流重绘引起的性能损耗;
③虚拟DOM有效降低⼤⾯积的重绘与排版,因为是和真实DOM对 ⽐,更新差异部分,所以只渲染局部。
13.axios和fetch区别?
①Axios是对XMLHttpRequest的封装,而Fetch是一种新的获取资源的接口方式。
②Fetch是浏览器原生支持,而Axios需要引入Axios库。
14.宏任务和微任务?
微任务是指在当前任务执行结束后立即执行的任务,它可以看作是在当前任务的“尾巴”添加的任务。常见的微任务包括 Promise 回调和 process.nextTick
。
宏任务是指需要排队等待 JavaScript 引擎空闲时才能执行的任务。常见的宏任务包括setTimeout、setInterval、I/O 操作、DOM 事件等。
15.webpack打包流程?
- 解析配置文件:Webpack 会读取并解析配置文件(通常是
webpack.config.js
文件),并根据配置生成一个 Compiler 对象。 - 读取入口文件:Webpack 根据配置中的入口文件,读取这些文件及其依赖的模块,并将它们组成一个依赖图。
- 解析模块依赖:Webpack 会根据模块之间的依赖关系,递归地解析它们的依赖,直到所有的依赖都被解析完毕。
- 加载模块:Webpack 会根据模块的路径,使用相应的 Loader 加载模块的源代码,并将其转换为 Webpack 可以处理的形式。
- 转换代码:Webpack 会根据配置中的插件,对加载的模块进行一系列的转换操作,比如压缩、合并、优化等。
- 生成代码:Webpack 会将所有模块转换后的代码合并成一个或多个文件,并输出到指定的输出目录中。
16.什么是垃圾回收机制?
垃圾回收机制是一种自动内存管理机制,用于清理未使用的内存。它通过检测不再使用的变量和对象,然后将其从内存中移除,以减少内存的使用量。
17.Promise 的方法有哪些,分别有什么作用?
promise.all()用于将多个 Promise 实例,包装成一个新的 Promise 实例。
Promise.race(iterable):返回一个promise,一旦迭代器中的某个promise解决或拒绝,返回的promise就会解决或者拒绝。
Promise.reject(reason)方法返回一个带有拒绝原因reason参数的Promise对象
Promise.resolve()将现有对象转为 Promise 对象。
18.说说你对 TypeScript 的理解?与 JavaScript 的区别?
TypeScript
是 JavaScript
的类型的超集,支持ES6
语法,支持面向对象编程的概念,如类、接口、继承、泛型等。
19.什么是事件循环机制?
事件循环是一种处理异步操作的机制,它可以让我们在代码执行过程中处理异步任务。事件循环的原理是将所有的异步任务放入一个事件队列中,然后依次执行队列中的任务,直到队列为空为止。
20.工厂模式和发布订阅者模式的区别?
工厂模式是一种创建型模式,旨在通过工厂类创建对象实例,而不是通过直接调用构造函数。这种模式通常使用一个工厂类,该类包含一个方法,该方法接受参数并返回新创建的对象。这个方法可以根据传递的参数来决定创建哪个对象。
发布订阅者模式是一种行为模式,通过解耦发布者和订阅者来实现松散耦合。在这种模式下,一个对象(发布者)发布一个事件,而其他对象(订阅者)订阅该事件。当事件被触发时,所有订阅者都会收到通知并执行相应的操作。
工厂模式是一种创建型模式,用于创建对象,而发布订阅者模式是一种行为模式,用于解耦发布者和订阅者。