问:ES5和ES6的区别

ES5与ES6详解:JavaScript语言标准的演进 🚀

本文档详细介绍ES5和ES6的区别、特性对比以及在现代前端开发中的应用。

📋 目录

  • [📚 什么是ES5和ES6?](#📚 什么是ES5和ES6?)
  • [📊 核心区别对比表](#📊 核心区别对比表)
  • [🔍 详细特性对比](#🔍 详细特性对比)
    • [1️⃣ 变量声明](#1️⃣ 变量声明)
    • [2️⃣ 函数定义](#2️⃣ 函数定义)
    • [3️⃣ 字符串处理](#3️⃣ 字符串处理)
    • [4️⃣ 对象和数组操作](#4️⃣ 对象和数组操作)
    • [5️⃣ 异步处理](#5️⃣ 异步处理)
    • [6️⃣ 类和继承](#6️⃣ 类和继承)
    • [7️⃣ 模块系统](#7️⃣ 模块系统)
  • [🎯 实际开发中的应用](#🎯 实际开发中的应用)
  • [🔍 如何检测项目ES版本](#🔍 如何检测项目ES版本)
  • [🌐 浏览器ES版本支持情况](#🌐 浏览器ES版本支持情况)
  • [💡 迁移建议](#💡 迁移建议)
  • [🔧 工具支持](#🔧 工具支持)
  • [📈 总结](#📈 总结)

📚 什么是ES5和ES6?

ES5 (ECMAScript 5)

  • 🗓️ 发布时间:2009年
  • 📖 定义:JavaScript语言的第5个版本标准
  • 🌐 兼容性:几乎所有现代浏览器都支持
  • 🎯 特点:相对保守,注重稳定性和兼容性

ES6 (ECMAScript 2015)

  • 🗓️ 发布时间:2015年
  • 📖 定义:JavaScript语言的重大更新版本
  • 🚀 特点:引入了大量新特性,现代JavaScript开发的基础
  • 🔄 别名:也称为ES2015,之后每年发布一个新版本

📊 核心区别对比表

特性 ES5 ES6
变量声明 var letconst
函数定义 function 箭头函数 =>
字符串处理 字符串拼接 模板字符串
对象操作 传统语法 解构赋值、扩展运算符
异步处理 回调函数 Promise、async/await
模块系统 无原生支持 import/export
类定义 构造函数 + 原型 class 语法

🔍 详细特性对比

1️⃣ 变量声明

ES5 - 只有 var
javascript 复制代码
// ES5 - 只有 var
var name = "张三";
var age = 25;
var age = 30; // 可以重复声明,容易出错

// 函数作用域问题
for (var i = 0; i < 3; i++) {
  setTimeout(function() {
    console.log(i); // 输出 3, 3, 3
  }, 100);
}
ES6 - let 和 const
javascript 复制代码
// ES6 - let 和 const
let name = "张三";     // 块级作用域,可修改
const age = 25;       // 块级作用域,不可修改
// let age = 30;      // 报错:不能重复声明

// 块级作用域解决问题
for (let i = 0; i < 3; i++) {
  setTimeout(function() {
    console.log(i); // 输出 0, 1, 2
  }, 100);
}

🎯 核心改进

  • 块级作用域:let/const提供块级作用域,避免变量污染
  • 重复声明检查:防止意外的变量重复声明
  • 暂时性死区:在声明前访问变量会报错,提高代码安全性

2️⃣ 函数定义

ES5 - 传统函数
javascript 复制代码
// ES5 - 传统函数
var add = function(a, b) {
  return a + b;
};

var obj = {
  name: "张三",
  sayHello: function() {
    var self = this; // 需要保存this
    setTimeout(function() {
      console.log("Hello, " + self.name);
    }, 1000);
  }
};
ES6 - 箭头函数
javascript 复制代码
// ES6 - 箭头函数
const add = (a, b) => a + b;

const obj = {
  name: "张三",
  sayHello() {
    setTimeout(() => {
      console.log(`Hello, ${this.name}`); // 自动绑定this
    }, 1000);
  }
};

🎯 核心改进

  • 语法简洁:箭头函数语法更简洁
  • this绑定:箭头函数自动绑定外层this
  • 隐式返回:单表达式可以省略return

3️⃣ 字符串处理

ES5 - 字符串拼接
javascript 复制代码
// ES5 - 字符串拼接
var name = "张三";
var age = 25;
var message = "我叫" + name + ",今年" + age + "岁";
var html = "<div>" +
           "  <h1>" + name + "</h1>" +
           "  <p>年龄:" + age + "</p>" +
           "</div>";
ES6 - 模板字符串
javascript 复制代码
// ES6 - 模板字符串
const name = "张三";
const age = 25;
const message = `我叫${name},今年${age}岁`;
const html = `
  <div>
    <h1>${name}</h1>
    <p>年龄:${age}</p>
  </div>
`;

🎯 核心改进

  • 插值表达式${}语法直接嵌入变量和表达式
  • 多行字符串:支持换行,无需转义
  • 可读性提升:代码更清晰,维护更容易

4️⃣ 对象和数组操作

ES5 - 传统操作
javascript 复制代码
// ES5 - 传统操作
var user = { name: "张三", age: 25, city: "北京" };
var name = user.name;
var age = user.age;

var arr = [1, 2, 3];
var newArr = arr.concat([4, 5]);

// 对象合并
var newUser = {};
for (var key in user) {
  newUser[key] = user[key];
}
newUser.job = "工程师";
ES6 - 解构赋值和扩展运算符
javascript 复制代码
// ES6 - 解构赋值和扩展运算符
const user = { name: "张三", age: 25, city: "北京" };
const { name, age } = user; // 解构赋值

const arr = [1, 2, 3];
const newArr = [...arr, 4, 5]; // 扩展运算符

// 对象扩展
const newUser = { ...user, job: "工程师" };

// 数组解构
const [first, second, ...rest] = [1, 2, 3, 4, 5];
console.log(first, second, rest); // 1, 2, [3, 4, 5]

🎯 核心改进

  • 解构赋值:快速提取对象和数组中的值
  • 扩展运算符:简洁的数组和对象合并语法
  • 默认值:解构时可以设置默认值

5️⃣ 异步处理

ES5 - 回调函数(回调地狱)
javascript 复制代码
// ES5 - 回调函数(回调地狱)
function getData(callback) {
  setTimeout(function() {
    callback(null, "数据1");
  }, 1000);
}

getData(function(err, data1) {
  if (err) return console.error(err);
  
  getData(function(err, data2) {
    if (err) return console.error(err);
    
    getData(function(err, data3) {
      if (err) return console.error(err);
      console.log(data1, data2, data3);
    });
  });
});
ES6 - Promise
javascript 复制代码
// ES6 - Promise
function getData() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve("数据");
    }, 1000);
  });
}

getData()
  .then(data1 => getData())
  .then(data2 => getData())
  .then(data3 => {
    console.log("所有数据获取完成");
  })
  .catch(err => console.error(err));
ES2017 - async/await (基于ES6 Promise)
javascript 复制代码
// ES2017 - async/await (基于ES6 Promise)
async function fetchAllData() {
  try {
    const data1 = await getData();
    const data2 = await getData();
    const data3 = await getData();
    console.log(data1, data2, data3);
  } catch (err) {
    console.error(err);
  }
}

🎯 核心改进

  • Promise链:避免回调地狱,链式调用更清晰
  • 错误处理:统一的catch处理机制
  • async/await:同步风格的异步代码

6️⃣ 类和继承

ES5 - 构造函数 + 原型
javascript 复制代码
// ES5 - 构造函数 + 原型
function Person(name, age) {
  this.name = name;
  this.age = age;
}

Person.prototype.sayHello = function() {
  console.log("Hello, I'm " + this.name);
};

function Student(name, age, school) {
  Person.call(this, name, age);
  this.school = school;
}

Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student;

Student.prototype.study = function() {
  console.log(this.name + " is studying at " + this.school);
};
ES6 - class 语法
javascript 复制代码
// ES6 - class 语法
class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
  
  sayHello() {
    console.log(`Hello, I'm ${this.name}`);
  }
}

class Student extends Person {
  constructor(name, age, school) {
    super(name, age);
    this.school = school;
  }
  
  study() {
    console.log(`${this.name} is studying at ${this.school}`);
  }
}

🎯 核心改进

  • class语法:更直观的面向对象编程
  • extends继承:简洁的继承语法
  • super关键字:方便调用父类方法

7️⃣ 模块系统

ES5 - 无原生模块支持
javascript 复制代码
// ES5 - 使用IIFE或第三方方案
// math.js
(function(global) {
  function add(a, b) {
    return a + b;
  }
  
  function subtract(a, b) {
    return a - b;
  }
  
  global.MathUtils = {
    add: add,
    subtract: subtract
  };
})(window);

// main.js
var result = MathUtils.add(1, 2);
ES6 - 原生模块支持
javascript 复制代码
// ES6 - 原生模块支持
// math.js
export function add(a, b) {
  return a + b;
}

export function subtract(a, b) {
  return a - b;
}

export default {
  add,
  subtract
};

// main.js
import { add, subtract } from './math.js';
import MathUtils from './math.js';

const result = add(1, 2);

🎯 核心改进

  • 原生模块:语言层面支持模块化
  • 静态分析:编译时确定依赖关系
  • Tree Shaking:支持无用代码消除

🎯 实际开发中的应用

ES5适用场景

  • 🏢 老项目维护:需要兼容IE8等老浏览器
  • 📚 学习基础:理解JavaScript核心概念
  • 🔧 简单脚本:不需要复杂功能的小工具

ES6+适用场景

  • 🚀 现代项目:React、Vue、Angular等框架开发
  • 📱 移动端开发:现代浏览器环境
  • 🛠️ 工程化项目:使用Webpack、Babel等工具链
  • 🌐 Node.js开发:服务端JavaScript开发

🔍 如何检测项目ES版本

在实际开发中,准确判断项目使用的ES版本对于代码编写、工具配置和团队协作都很重要。

1️⃣ 查看项目配置文件

package.json 检查
json 复制代码
{
  "name": "my-project",
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not dead",
    "not ie 11"  // 不支持IE11说明可能使用ES6+
  ],
  "devDependencies": {
    "@babel/core": "^7.22.0",        // 有Babel说明可能用ES6+
    "@babel/preset-env": "^7.22.0",  // 转译配置
    "typescript": "^5.1.0"           // TS项目通常用ES6+
  },
  "engines": {
    "node": ">=14.0.0"  // Node版本要求也能反映ES支持
  }
}
Babel配置检查
javascript 复制代码
// .babelrc 或 babel.config.js
{
  "presets": [
    ["@babel/preset-env", {
      "targets": {
        "browsers": ["> 1%, not dead, not ie 11"]
      }
    }]
  ]
}

// 如果有Babel配置,说明项目使用ES6+语法,需要转译
TypeScript配置检查
json 复制代码
// tsconfig.json
{
  "compilerOptions": {
    "target": "ES2020",        // 编译目标
    "module": "ESNext",        // 模块系统
    "lib": ["ES2020", "DOM"]   // 使用的库
  }
}

2️⃣ 代码语法分析

ES6+特征检测
javascript 复制代码
// 检查项目中是否使用了ES6+语法

// 1. 变量声明
const name = 'John';     // ES6
let age = 25;           // ES6
var oldStyle = 'old';   // ES5

// 2. 箭头函数
const add = (a, b) => a + b;  // ES6
function add(a, b) {          // ES5
  return a + b;
}

// 3. 模板字符串
const message = `Hello, ${name}!`;  // ES6
var message = 'Hello, ' + name;     // ES5

// 4. 解构赋值
const { x, y } = point;  // ES6
var x = point.x;         // ES5
var y = point.y;

// 5. 类语法
class MyClass {          // ES6
  constructor() {}
}
function MyClass() {}    // ES5

// 6. 模块导入导出
import React from 'react';     // ES6
export default Component;      // ES6
var React = require('react');  // CommonJS/ES5

3️⃣ 工具检测方法

使用命令行工具检测
bash 复制代码
# 1. 使用es-check检查代码ES版本
npm install -g es-check
es-check es5 './src/**/*.js'  # 检查是否符合ES5
es-check es6 './src/**/*.js'  # 检查是否符合ES6

# 2. 快速语法检查
grep -r "const\|let\|=>" src/ && echo "ES6+" || echo "可能是ES5"

# 3. 检查模块语法
grep -r "import\|export" src/ && echo "ES6模块" || echo "CommonJS/ES5"

# 4. 检查Babel配置
[ -f .babelrc ] || [ -f babel.config.js ] && echo "使用Babel转译" || echo "无转译配置"
自动化检测脚本
javascript 复制代码
// detect-es-version.js
const fs = require('fs');
const path = require('path');

function detectESVersion(projectPath = '.') {
  const results = {
    configFiles: {},
    codeFeatures: {
      es5: 0,
      es6: 0,
      es2017: 0,
      es2020: 0
    },
    conclusion: ''
  };

  // 检查配置文件
  const configFiles = ['package.json', '.babelrc', 'tsconfig.json'];
  configFiles.forEach(file => {
    if (fs.existsSync(path.join(projectPath, file))) {
      results.configFiles[file] = true;
    }
  });

  // 扫描代码特征
  function scanFile(filePath) {
    const content = fs.readFileSync(filePath, 'utf8');
    
    // ES5特征
    if (content.includes('var ') || content.includes('function ')) {
      results.codeFeatures.es5++;
    }
    
    // ES6特征
    if (content.includes('const ') || content.includes('let ') || 
        content.includes('=>') || content.includes('import ')) {
      results.codeFeatures.es6++;
    }
    
    // ES2017特征
    if (content.includes('async ') || content.includes('await ')) {
      results.codeFeatures.es2017++;
    }
    
    // ES2020特征
    if (content.includes('?.') || content.includes('??')) {
      results.codeFeatures.es2020++;
    }
  }

  // 得出结论
  const { es5, es6, es2017, es2020 } = results.codeFeatures;
  
  if (es2020 > 0) {
    results.conclusion = 'ES2020+';
  } else if (es2017 > 0) {
    results.conclusion = 'ES2017+';
  } else if (es6 > es5) {
    results.conclusion = 'ES6+';
  } else {
    results.conclusion = 'ES5';
  }

  return results;
}

4️⃣ 项目类型判断

根据项目特征判断
javascript 复制代码
/**
 * 项目类型与ES版本的关系
 */

// 1. 传统jQuery项目
const jqueryProject = {
  features: ['jQuery', 'global variables', 'IIFE'],
  esVersion: 'ES5',
  signs: ['<script src="jquery.js">', 'var declarations', 'function expressions']
};

// 2. 现代框架项目
const modernFramework = {
  features: ['React/Vue/Angular', 'npm/yarn', 'bundler'],
  esVersion: 'ES6+',
  signs: ['import/export', 'const/let', 'arrow functions', 'JSX']
};

// 3. Node.js项目
const nodeProject = {
  features: ['package.json', 'node_modules', 'npm scripts'],
  esVersion: 'depends on Node version',
  signs: ['require() or import', 'module.exports or export']
};

🌐 浏览器ES版本支持情况

了解不同浏览器对ES版本的支持情况,有助于我们做出正确的技术选型决策。

📊 主流浏览器ES支持表

ES版本 Chrome Firefox Safari Edge IE
ES5 23+ 21+ 6+ 12+ 9+
ES6 (ES2015) 51+ 54+ 10+ 14+
ES2017 55+ 52+ 10.1+ 15+
ES2018 64+ 58+ 11.1+ 79+
ES2019 73+ 62+ 12+ 79+
ES2020 80+ 72+ 13.1+ 80+
ES2021 85+ 84+ 14+ 85+
ES2022 94+ 93+ 15.4+ 94+

🎯 关键特性支持情况

ES6核心特性支持
ES6特性 Chrome Firefox Safari Edge 支持状态
变量声明 (let/const) 49+ 44+ 10+ 12+ ✅ 广泛支持
箭头函数 (=>) 45+ 22+ 10+ 12+ ✅ 广泛支持
模板字符串 (${}) 41+ 34+ 9+ 12+ ✅ 广泛支持
解构赋值 49+ 41+ 8+ 14+ ✅ 较好支持
类语法 (class) 49+ 45+ 9+ 13+ ✅ 较好支持
模块系统 (import/export) 61+ 60+ 10.1+ 16+ ⚠️ 需要注意兼容性
ES2017+新特性支持
现代特性 Chrome Firefox Safari Edge 支持状态
async/await (ES2017) 55+ 52+ 10.1+ 14+ ✅ 现代浏览器支持
可选链 (?.) (ES2020) 80+ 72+ 13.1+ 80+ ⚠️ 较新特性,需要polyfill
空值合并 (??) (ES2020) 80+ 72+ 13.1+ 80+ ⚠️ 较新特性,需要polyfill
私有字段 (#field) (ES2022) 74+ 90+ 14.1+ 79+ 🔄 逐步支持中

📱 移动端浏览器支持

移动端ES支持情况
移动端平台 ES6支持 ES2017支持 ES2020支持 特点说明
iOS Safari iOS 10+ iOS 10.3+ iOS 13.4+ 通常支持较好,更新较快
Android Chrome Android 5.0+ Android 6.0+ Android 8.0+ 跟随Chrome版本,支持较好
Android WebView Android 5.0+ Android 7.0+ Android 8.0+ 依赖系统版本,兼容性需要注意
微信小程序 ✅ 支持 ✅ 支持 ⚠️ 部分支持 有自己的JavaScript引擎

🛠️ 兼容性策略建议

根据目标用户选择ES版本
应用场景 目标ES版本 浏览器支持 推荐工具 核心特性
企业级应用 ES5 + 部分ES6 IE11+, Chrome 60+, Firefox 55+ Babel转译, Polyfill const/let, 箭头函数, 模板字符串
现代Web应用 ES2018+ Chrome 70+, Firefox 65+, Safari 12+ Babel (minimal), Core-js async/await, 解构赋值, 扩展运算符
移动端应用 ES2020 iOS 13+, Android 8+ Vite, esbuild 可选链, 空值合并, 动态导入
内部工具/管理后台 ES2022 最新版Chrome/Firefox 原生ES模块, TypeScript 私有字段, Top-level await, 所有新特性
渐进增强策略
策略层级 目标版本 核心特性 浏览器支持 降级方案
基础层 ES5 基础语法, 核心API 所有浏览器 无需降级
增强层 ES6 const/let, 箭头函数, 模板字符串 现代浏览器 Babel转译
优化层 ES2020+ 可选链, 空值合并, 动态导入 最新浏览器 Polyfill或降级

🔧 检测和适配工具

浏览器特性检测
javascript 复制代码
/**
 * 运行时ES特性检测
 */

function detectESSupport() {
  const support = {};
  
  // 检测ES6基础特性
  try {
    eval('const x = 1; let y = 2;');
    support.es6Variables = true;
  } catch (e) {
    support.es6Variables = false;
  }
  
  // 检测箭头函数
  try {
    eval('() => {}');
    support.arrowFunctions = true;
  } catch (e) {
    support.arrowFunctions = false;
  }
  
  // 检测模板字符串
  try {
    eval('`template ${1} string`');
    support.templateLiterals = true;
  } catch (e) {
    support.templateLiterals = false;
  }
  
  // 检测可选链 (ES2020)
  try {
    eval('const obj = {}; obj?.prop');
    support.optionalChaining = true;
  } catch (e) {
    support.optionalChaining = false;
  }
  
  return support;
}

// 使用示例
const browserSupport = detectESSupport();
console.log('浏览器ES特性支持:', browserSupport);
Browserslist配置
javascript 复制代码
// 根据目标浏览器自动确定ES版本支持
// package.json
{
  "browserslist": [
    // 保守策略
    "> 1%, not dead, not ie 11",
    
    // 现代策略  
    "last 2 versions, > 2%",
    
    // 激进策略
    "last 1 version, > 5%"
  ]
}

// 查看当前配置支持的浏览器
// npx browserslist

💡 迁移建议

渐进式迁移策略

javascript 复制代码
/**
 * 从ES5到ES6的渐进式迁移
 */

// 1. 优先替换变量声明
// ❌ ES5
var userName = "张三";

// ✅ ES6
const userName = "张三";
let userAge = 25;

// 2. 使用箭头函数简化代码
// ❌ ES5
array.map(function(item) {
  return item * 2;
});

// ✅ ES6
array.map(item => item * 2);

// 3. 使用模板字符串
// ❌ ES5
var message = "用户" + userName + "年龄" + userAge;

// ✅ ES6
const message = `用户${userName}年龄${userAge}`;

// 4. 使用解构赋值
// ❌ ES5
var name = user.name;
var age = user.age;

// ✅ ES6
const { name, age } = user;

// 5. 使用Promise替代回调
// ❌ ES5 回调地狱
fetchData(function(err, data) {
  if (err) return handleError(err);
  processData(data, function(err, result) {
    if (err) return handleError(err);
    console.log(result);
  });
});

// ✅ ES6 Promise链
fetchData()
  .then(data => processData(data))
  .then(result => console.log(result))
  .catch(err => handleError(err));

迁移优先级

  1. 🔥 高优先级

    • 变量声明(var → let/const)
    • 字符串处理(拼接 → 模板字符串)
    • 函数简化(function → 箭头函数)
  2. ⚡ 中优先级

    • 对象操作(传统 → 解构赋值)
    • 异步处理(回调 → Promise)
    • 数组操作(传统 → 扩展运算符)
  3. 📚 低优先级

    • 类定义(构造函数 → class)
    • 模块系统(IIFE → import/export)

🔧 工具支持

Babel转译配置

javascript 复制代码
// 现代开发中,可以写ES6+代码,通过Babel转译为ES5
// .babelrc 配置
{
  "presets": ["@babel/preset-env"],
  "targets": {
    "browsers": ["> 1%", "last 2 versions", "ie >= 9"]
  }
}

// 开发时写ES6
const getData = async () => {
  const response = await fetch('/api/data');
  return response.json();
};

// 编译后的ES5(简化版)
function getData() {
  return regeneratorRuntime.async(function getData$(_context) {
    // ... 转译后的代码
  });
}

现代工具链

json 复制代码
// package.json
{
  "devDependencies": {
    "@babel/core": "^7.0.0",
    "@babel/preset-env": "^7.0.0",
    "webpack": "^5.0.0",
    "eslint": "^8.0.0"
  },
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not dead"
  ]
}

ESLint配置

javascript 复制代码
// .eslintrc.js
module.exports = {
  env: {
    browser: true,
    es6: true,
    node: true
  },
  extends: [
    'eslint:recommended'
  ],
  parserOptions: {
    ecmaVersion: 2018,
    sourceType: 'module'
  },
  rules: {
    'prefer-const': 'error',
    'no-var': 'error',
    'prefer-arrow-callback': 'warn',
    'prefer-template': 'warn'
  }
};

📈 总结

ES5 vs ES6的本质区别

  1. 🎯 设计理念

    • ES5:稳定、兼容、渐进式改进
    • ES6:革命性更新、现代化、开发效率
  2. 💻 开发体验

    • ES5:语法冗长、容易出错、开发效率低
    • ES6:语法简洁、类型安全、开发效率高
  3. 🏗️ 项目架构

    • ES5:依赖第三方库实现模块化
    • ES6:原生模块系统、更好的工程化支持
  4. 🚀 性能优化

    • ES5:手动优化、经验依赖
    • ES6:引擎优化、更好的性能特性

选择建议

  • 🆕 新项目:直接使用ES6+,配合Babel转译
  • 🔄 老项目:渐进式迁移,优先替换高频使用的特性
  • 📚 学习路径:先掌握ES5基础,再学习ES6新特性

未来趋势

  • ES2016+:每年发布新版本,持续演进
  • TypeScript:类型安全的JavaScript超集
  • 现代框架:React、Vue、Angular全面拥抱ES6+
  • 工具链成熟:Babel、Webpack、Vite等工具完善

记住:ES6不仅仅是语法糖,它代表了JavaScript语言的现代化转型! 🎯

欢迎大家关注👇🏻【爱码说】,文章同步更新推送!

相关推荐
永不停歇的蜗牛1 小时前
Maven的POM文件相关标签作用
服务器·前端·maven
芳草萋萋鹦鹉洲哦1 小时前
【vue/js】文字超长悬停显示的几种方式
前端·javascript·vue.js
HIT_Weston2 小时前
47、【Ubuntu】【Gitlab】拉出内网 Web 服务:Nginx 事件驱动分析(一)
前端·ubuntu·gitlab
开发者小天2 小时前
React中的 闭包陷阱
前端·javascript·react.js
翔云 OCR API2 小时前
承兑汇票识别接口技术解析-开发者接口
开发语言·前端·数据库·人工智能·ocr
涔溪2 小时前
Vue3 的核心语法
前端·vue.js·typescript
G***E3163 小时前
前端在移动端中的React Native Web
前端·react native·react.js
云烟飘渺o3 小时前
JPA 的脏检查:一次“没 save() 却更新了”的排查记录
前端
Neptune13 小时前
深入浅出:理解js的‘万物皆对象’与原型链
前端·javascript