前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >2025最新出炉--前端面试题十一

2025最新出炉--前端面试题十一

作者头像
全栈若城
发布2025-02-18 10:53:46
发布2025-02-18 10:53:46
6500
代码可运行
举报
文章被收录于专栏:若城技术专栏若城技术专栏
运行总次数:0
代码可运行
1. js 里面的垃圾回收机制都有哪些

回答: JavaScript 的垃圾回收机制主要包含以下方法:

  1. 标记清除(Mark-and-Sweep)
    • 原理:遍历所有对象,标记所有从根(全局对象、当前执行上下文)可达的对象,清除未标记的对象。
    • 优点:解决循环引用问题。
    • 缺点:可能引起内存碎片。
  2. 引用计数(Reference Counting)
    • 原理:记录每个对象被引用的次数,当引用数为 0 时回收。
    • 缺点:无法处理循环引用(如 a.prop = b; b.prop = a)。
  3. 分代回收(Generational Collection)
    • 原理:V8 引擎将内存分为 新生代(存活时间短的对象)和 老生代(存活时间长的对象)。
      • 新生代:使用 Scavenge 算法(复制存活对象到新空间)。
      • 老生代:使用 标记清除 + 标记整理(整理内存碎片)。
  4. 增量标记(Incremental Marking)
    • 原理:将标记过程分解为多个小步骤,避免长时间阻塞主线程。

示例

代码语言:javascript
代码运行次数:0
复制
// 循环引用导致引用计数失效
let a = {};
let b = {};
a.prop = b;
b.prop = a;
// 手动解除引用
a = null;
b = null;

2. nginx 和 nodejs 相关的做过吗

回答: 是的,以下为相关经验:

Nginx 配置

反向代理:将请求转发到 Node.js 服务。

代码语言:javascript
代码运行次数:0
复制
server {
    listen 80;
    server_name example.com;
    location / {
        proxy_pass http://localhost:3000;
        proxy_set_header Host $host;
    }
}

负载均衡:分发请求到多个 Node.js 实例。

代码语言:javascript
代码运行次数:0
复制
upstream node_servers {
    server 127.0.0.1:3000;
    server 127.0.0.1:3001;
}
server {
    location / {
        proxy_pass http://node_servers;
    }
}

静态资源托管:直接返回 CSS、JS 等文件。

代码语言:javascript
代码运行次数:0
复制
location /static {
    root /var/www;
    expires 30d;
}

Node.js 实践

  • RESTful API:使用 Express/Koa 开发后端接口。
  • SSR 服务:基于 Nuxt.js/Next.js 实现服务端渲染。
  • WebSocket 服务:使用 ws 库实现实时通信。

3. vue 里数据双向绑定原理是怎样的

回答:

Vue 的数据双向绑定通过 响应式系统 实现,具体分 Vue2 和 Vue3:

Vue2(基于 Object.defineProperty)
  1. 数据劫持:递归遍历对象,用 Object.defineProperty 为每个属性添加 getter/setter
  2. 依赖收集:在 getter 中收集依赖(Watcher)。
  3. 派发更新:在 setter 中通知依赖更新,触发视图渲染。

缺陷

  • 无法检测新增/删除属性(需 Vue.set/Vue.delete)。
  • 数组变异方法(如 push)需重写。
Vue3(基于 Proxy)
  1. 代理对象Proxy 拦截对象的所有操作(getsetdeleteProperty)。
  2. 依赖跟踪:通过 track 函数收集依赖。
  3. 触发更新:通过 trigger 函数通知更新。

优势

  • 支持深层对象和数组监听。
  • 性能更优(惰性依赖收集)。

代码示例

代码语言:javascript
代码运行次数:0
复制
// Vue3 Proxy 实现简例
const data = { count: 0 };
const proxy = new Proxy(data, {
  get(target, key) {
    track(target, key); // 收集依赖
    return target[key];
  },
  set(target, key, value) {
    target[key] = value;
    trigger(target, key); // 触发更新
    return true;
  }
});

4. 你觉得 es6 的 proxy 有怎样的问题

回答: Proxy 的潜在问题包括:

  1. 兼容性
    • 不支持 IE11 及更低版本浏览器。
    • 需通过 Babel 或 polyfill 兼容旧环境。
  2. 性能开销
    • 代理复杂对象时,可能比直接访问属性慢。
    • 频繁操作代理对象时需注意优化(如缓存访问路径)。
  3. 调试困难
    • 代理对象在控制台打印时可能显示为 Proxy,而非原始对象。

示例

代码语言:javascript
代码运行次数:0
复制
const obj = { a: 1 };
const proxy = new Proxy(obj, {
  get(target, key) {
    console.log('读取:', key);
    return target[key];
  }
});
console.log(proxy.a); // 输出:读取: a → 1
console.log(proxy);   // 控制台显示 Proxy 对象

5. 这三种声明方式 var, let, const 的区别

回答:

特性

var

let

const

作用域

函数作用域或全局作用域。

块级作用域({} 内有效)。

块级作用域。

变量提升

声明提升到作用域顶部。

存在暂时性死区(TDZ),不可在声明前使用。

同 let。

重复声明

允许重复声明。

同一作用域内禁止重复声明。

同 let。

值可变性

可重新赋值。

可重新赋值。

不可重新赋值(对象属性可修改)。

示例

代码语言:javascript
代码运行次数:0
复制
// 作用域
if (true) {
  var a = 1;
  let b = 2;
}
console.log(a); // 1
console.log(b); // ReferenceError

// 暂时性死区
console.log(c); // undefined(var 提升)
var c = 3;
console.log(d); // ReferenceError(let 不提升)
let d = 4;

6. const 为什么不可以更改

回答: const 声明的变量是 常量绑定,规则如下:

基本类型:值不可变(如 const a = 1; a = 2 会报错)。

引用类型:内存地址不可变,但对象属性可修改。

代码语言:javascript
代码运行次数:0
复制
const obj = { name: 'Alice' };
obj.name = 'Bob'; // 允许
obj = {};         // TypeError

原理

  • const 确保变量指向的内存地址不变,而非内存中的数据不变。

7. 箭头函数跟普通函数之间有什么区别

回答:

特性

普通函数

箭头函数

this 绑定

动态绑定(由调用方式决定)。

静态绑定(继承定义时的外层 this)。

arguments

可用 arguments 对象获取参数。

无 arguments,需用剩余参数(...args)。

构造函数

可作为构造函数(new 调用)。

不可作为构造函数。

原型属性

有 prototype 属性。

无 prototype。

方法简写

对象方法需完整定义:method: function() {}。

可简写为:method() {}(但此时是普通函数)。

示例

代码语言:javascript
代码运行次数:0
复制
// this 绑定差异
const obj = {
  name: 'obj',
  regularFunc: function() {
    console.log(this.name); // 'obj'
  },
  arrowFunc: () => {
    console.log(this.name); // undefined(外层无 name)
  }
};
obj.regularFunc();
obj.arrowFunc();

8. es6 里面的 promise 和 async/await 有什么区别

回答:

特性

Promise

async/await

语法

链式调用(.then、.catch)。

同步写法,基于 try/catch 处理错误。

可读性

嵌套较多时易产生回调地狱。

代码更扁平,逻辑更清晰。

错误处理

需通过 .catch 或链式调用处理。

可直接用 try/catch 捕获错误。

执行顺序

微任务,优先级高于宏任务。

本质是 Promise 的语法糖,执行规则相同。

代码对比

代码语言:javascript
代码运行次数:0
复制
// Promise
function fetchData() {
  return fetch('/api')
    .then(response => response.json())
    .catch(error => console.error(error));
}

// async/await
async function fetchData() {
  try {
    const response = await fetch('/api');
    return await response.json();
  } catch (error) {
    console.error(error);
  }
}

本质关系

  • async 函数返回一个 Promise 对象。
  • await 后面必须跟一个 Promise,否则会被转换为立即解决的 Promise。
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-02-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. js 里面的垃圾回收机制都有哪些
  • 2. nginx 和 nodejs 相关的做过吗
  • 3. vue 里数据双向绑定原理是怎样的
    • Vue2(基于 Object.defineProperty)
    • Vue3(基于 Proxy)
  • 4. 你觉得 es6 的 proxy 有怎样的问题
  • 5. 这三种声明方式 var, let, const 的区别
  • 6. const 为什么不可以更改
  • 7. 箭头函数跟普通函数之间有什么区别
  • 8. es6 里面的 promise 和 async/await 有什么区别
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档