三维家
2024-08-11
-
对于 new 出来的对象 a 的属性查找的顺序 person = new Person(); person.a
答:先从 Person 上找,找不到,去找 Person 的原型链,找不到,到顶层 找不到 返回 undefined
G:当你用
new创建对象时,属性查找顺序是:首先在对象自身查找属性,如果没找到,就查找对象的原型(__proto__),然后是原型的原型,以此类推,直到找到属性或到达Object.prototype。如果最终还是没找到,则返回undefined。 -
ts 与 js 的区别
答: (1) 数据系统 ts 是强类型语言,在开发是定义数据类型 js 是弱类型语言,变量的类型是在运行时决定的 (2) 编译 ts: 需要经过编译,所有的 ts 编译成 js 文件才能在浏览器或者 node 环境中运行 js: 不需要编译,直接在浏览器或 node 环境中运行
-
ajax(Asynchronous JavaScript and XML) 和 axios 区别,axios 有那些优势
答: (1) axios 是基于 promise 封装的,ajax 是基于 XHR(XMLHttpRequest)封装的
G: ajax 是一种技术,实际是使用 js 进行异步请求的技术集合 特点: 原生支持:XMLHttpRequest 是浏览器原生就支持的技术 使用复杂性:使用 XHR 进行请求时,代码很冗长,处理异步操作和错误需要更多的手动控制 回调函数:原生的 AJAX 使用回调函数处理异步请求的响应,可能会导致回调地狱 示例:
var xhr = new XMLHttpRequest() xhr.open('get', 'https://api.example.com/data', true) // truei表示开启异步请求 xhr.onreadystatechange = function () { if (xhr.readyState === 4 && xhr.readyState === 200) { console.log(xhr.responseText) } } xhr.send()axios 是一个基于 Promise 的 HTTP 客户端,用于浏览器和 node,封装了对 XMLHttpRequest 的 API 使用 特点: 基于 Promise: 对异步请求和处理更加的简洁 简洁的 API:支持配置请求头、请求参数、响应拦截器等 请求和响应拦截器: 支持配置请求和响应拦截器,允许在请求前和响应后做一些处理 自动转换 JSON:自动将 JSON 响转换成 JS 对象 取消请求:提供取消请求的功能,在请求发出后根据需要取消请求 处理请求超时:支持配置请求超时的时间 Axios 优势: 简化代码:对异步请求和处理都很简洁 基于 Promise 请求和响应拦截器 自动转换 JSON 取消请求 处理请求超时 总结: AJAX 是一种技术,用于实现异步请求,XMLHttpReauest 是其实现方式之一 Axios 是一个功能丰富的 HTTP 客户端库,提供了基于 Promise 的接口、拦截器、自动转换 JSON 等功能 发散: AJAX 怎么处理请求的响应的?
// 1. 创建 XMLHttpRequest 对象 var xhr = new XMLHttpRequest() // 2. 配置请求 // 设置请求的类型(GET、POST等)和目标 URL。可以选择是否异步(true 为异步)。 xhr.open('GET', 'https://api.example.com/data', true) // 3. 设置回调函数 // 使用 onreadystatechange 事件来监听请求状态变化。请求完成时(readyState 为 4),检查状态码(status 为 200)以确保请求成功。 xhr.onreadystatechange = function () { if (xhr.readyState === 4) { // 请求完成 if (xhr.status === 200) { // 请求成功 // 处理响应数据 console.log(xhr.responseText) } else { // 处理错误 console.error('Error:', xhr.statusText) } } } // 4. 发送请求 xhr.send() // 5. 处理响应数据 // 根据需要解析响应数据。对于文本响应,可以直接使用 xhr.responseText,对于 JSON 响应,则需要使用 JSON.parse() 解析。 var responseData = JSON.parse(xhr.responseText) console.log(responseData)Axios 怎么处理请求的响应的?
// 1. 发送请求 // 使用 axios 方法(如 axios.get、axios.post 等)发送请求。 axios.get('https://api.example.com/data') .then(response => { // 处理成功响应 console.log(response.data); }) .catch(error => { // 处理错误 console.error("Error:", error); }); //2. 响应处理 // Axios 会自动将响应数据解析为 JSON 对象(如果响应头中的 Content-Type 是 application/json),并将其封装在 response 对象中。 //3. 请求和响应拦截器 // Axios 允许设置拦截器,用于在请求发送前或响应接收后处理数据。例如,添加认证 token 或处理错误: // 请求拦截器 axios.interceptors.request.use(config => { // 在请求发送之前做些什么 config.headers['Authorization'] = 'Bearer token'; return config; }, error => { return Promise.reject(error); }); // 响应拦截器 axios.interceptors.response.use(response => { // 对响应数据做些什么 return response; }, error => { // 对响应错误做些什么 return Promise.reject(error); }); // 4. 错误处理 // 如果请求失败(如网络错误或状态码不是 2xx),catch 方法会捕获异常: axios.get('https://api.example.com/data') .then(response => { // 处理成功响应 console.log(response.data); }) .catch(error => { // 处理错误 console.error("Error:", error.message); }); -
面向对象的特征
答:
G:
封装: js 的对象、闭包可以实现定义私有属性和私有方法 es6 的类
class Person { constructor(name, age) { this.name = name; // 公共属性 let _age = age; // 私有属性,无法直接访问 this.getAge = function() { return _age; }; } greet() { console.log(`Hello, my name is ${this.name}`); } } const john = new Person('John', 30); john.greet(); // "Hello, my name is John" console.log(john.getAge()); // 30继承: js 的原型继承 类的 extends 继承
class Animal { constructor(name) { this.name = name; } speak() { console.log(`${this.name} makes a noise.`); } } class Dog extends Animal { speak() { console.log(`${this.name} barks.`); } } const dog = new Dog('Rex'); dog.speak(); // "Rex barks."多态: 子类重写父类的方法
class Shape { draw() { console.log('Drawing a shape'); } } class Circle extends Shape { draw() { console.log('Drawing a circle'); } } class Square extends Shape { draw() { console.log('Drawing a square'); } } const shapes = [new Circle(), new Square()]; shapes.forEach(shape => shape.draw()); // "Drawing a circle" // "Drawing a square"抽象:
js 定义抽象类,抽象类不能实例化,只能通过子类继承,子类完成实例化
class AbstractVehicle { constructor() { if (new.target === AbstractVehicle) { throw new Error('Cannot instantiate an abstract class.'); } } startEngine() { throw new Error('You have to implement the method startEngine!'); } } class Car extends AbstractVehicle { startEngine() { console.log('Car engine started.'); } } const myCar = new Car(); myCar.startEngine(); // "Car engine started." -
你熟悉的设计模式
答:
-
介绍下 HTTP
答:
G:HTTP(HyperHText Transfer Protocol,超文本传输协议)是用于在客户端和服务器之间传输超文本数据的协议。它是 Web 通信的基础
(1) 基本概念
- 客户端与服务器: HTTP 是基于客户端-服务器模型的协议。客户端(通常是浏览器)发起请求,服务器接收请求并返回响应。服务器提供资源,客户端通过 HTTP 请求这些资源。
- 请求与响应: 每次 HTTP 通信包括一次请求和一次响应。客户端通过 HTTP 请求资源,服务器处理请求并返回响应,包括请求的资源或状态信息。
(2) HTTP 方法
- GET: 请求指定资源。GET 请求通常用于请求数据而不改变服务器上的资源。
- POST: 向服务器提交数据,用于创建或更新资源。POST 通常用于表单提交。
- PUT: 向服务器上传资源,通常用于更新资源。
- DELETE: 删除指定资源。
- HEAD: 类似于 GET 请求,但不返回响应体,只获取响应头部。
- OPTIONS: 获取服务器支持的请求方法。
- PATCH: 对资源进行部分修改。
(3) HTTP 状态码
- 1xx(信息性状态码): 表示请求已接收,继续处理。
- 2xx(成功状态码): 表示请求已成功处理。例如,
200 OK表示请求成功,服务器返回了请求的资源。 - 3xx(重定向状态码): 表示资源已被移动,需要客户端采取进一步的操作。例如,
301 Moved Permanently表示资源已永久移动。 - 4xx(客户端错误状态码): 表示客户端请求有错误。例如,
404 Not Found表示请求的资源在服务器上不存在。 - 5xx(服务器错误状态码): 表示服务器端出现错误,无法完成请求。例如,
500 Internal Server Error表示服务器遇到未知错误。
(4) HTTP 头
- HTTP 头包含了客户端和服务器之间传输的元数据,用于描述请求或响应的属性。
- 请求头: 例如
User-Agent(浏览器信息)、Accept(客户端接受的媒体类型)、Authorization(身份验证信息)。 - 响应头: 例如
Content-Type(响应内容类型)、Set-Cookie(服务器设置的 cookie)、Cache-Control(缓存指令)。
(5) HTTP 版本
- HTTP/1.0: 是最初的版本,每次请求都需要建立一个新的连接。
- HTTP/1.1: 改进了性能,支持持久连接、管道化请求和更多的缓存控制机制。
- HTTP/2: 引入了二进制协议、多路复用、压缩头等特性,大大提升了性能。
- HTTP/3: 基于 QUIC 协议,进一步减少了延迟并改善了安全性和连接恢复。
(6) 无状态协议
- HTTP 是一种无状态协议,即每个请求都是独立的,不依赖于之前的请求或响应。每次请求和响应都是全新的。这种无状态特性简化了服务器的设计,但需要通过额外的机制(如 cookies、session、token)来维护状态信息。
-
UDP和TCP的区别
答:
(1) 可靠性 UDP 不可靠 TCP 可靠 UDP 不经过确认只是发送信息,不在乎信息是否传达了,TCP 经过三次握手,确保信息传达的可靠性
G:
(1) 连接性
TCP需要面链接的协议,传输前三次握手,四次挥手,UDP无连接协议,直接将数据包发到目方
(2) 可靠性
UDP不可靠。TCP可靠。丢包会自动从传
(3) 传输速度
UDP快,TCP慢
(4) 传输数据
TCP以字节流的形式传输,UDP是面向数据包的协议
(5) 应用场景
TCP: 网页浏览、文件传输、电子邮件、远程登录
UDP:实时视频或音频传输,在线游戏,DNS查询
-
算法题:用队列实现一个栈 队头 1 2 3 4 5 队尾 先进先出 栈顶 5 4 3 2 1 栈底 先进后出
/*
* @Author: Kvon
* @Date: 2024-08-11 19:12:45
* @Description:
*/
class MyStack {
constructor() {
this.queue1 = []
this.queue2 = []
}
push(v) {
this.queue2.push(v)
while (this.queue1.length > 0) {
this.queue2.push(this.queue1.shift()) // 队1 暂存值 永远保持空
}
;[this.queue1, this.queue2] = [this.queue2, this.queue1] // 队1 一把拿到值
}
pop() {
return this.queue1.shift()
}
top() {
return this.queue1[0]
}
empty() {
return this.queue1.length === 0
}
}
const stack = new MyStack()
stack.push(1)
stack.push(2)
stack.push(3)
stack.push(4)
stack.push(5)
while (!stack.empty()) {
console.log(stack.pop())
}