(正文开始)
1995年网景公司工程师Brendan Eich用10天时间创造了JavaScript语言,这个匆忙诞生的脚本语言在随后的二十多年里经历了惊人的进化。从最初简单的表单验证工具,到如今支撑起整个现代Web生态的完整编程语言,ECMAScript标准的演进堪称计算机史上最成功的标准化进程之一。理解ES3到ES6的演变过程,就是理解现代Web开发技术根基的关键。
ES3规范于1999年12月发布,确立了JavaScript作为动态类型语言的核心特征:
| |
| function createPerson(name) { |
| return { |
| name: name, |
| greet: function() { |
| alert("Hello, " + this.name); |
| } |
| }; |
| } |
| |
| var person = createPerson("John"); |
| person.greet(); |
这段代码展示了ES3时代的典型特征:基于原型的对象系统、函数作为一等公民、动态this绑定等核心概念。此时的JavaScript已经具备闭包等高级特性:
| |
| function createCounter() { |
| var count = 0; |
| return { |
| increment: function() { |
| count++; |
| }, |
| getValue: function() { |
| return count; |
| } |
| }; |
| } |
| |
| var counter = createCounter(); |
| counter.increment(); |
| console.log(counter.getValue()); |
ES3首次引入了try/catch异常处理结构,这对构建健壮的应用程序至关重要:
| try { |
| undefinedFunction(); |
| } catch (e) { |
| console.log("Error occurred:", e.message); |
| } finally { |
| console.log("Cleanup operations"); |
| } |
正则表达式在ES3中成为语言标准的一部分,其语法沿用至今:
| var pattern = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$/; |
| console.log(pattern.test("test@example.com")); |
虽然ES3奠定了语言基础,但存在诸多问题:
| for (var i = 0; i < 5; i++) { |
| setTimeout(function() { |
| console.log(i); |
| }, 100); |
| } |
- 严格相等运算符的缺失(== 的类型转换问题)
- 数组方法的匮乏(缺乏现代高阶函数)
"use strict"指令彻底改变了JavaScript的容错性:
| function strictExample() { |
| "use strict"; |
| undeclaredVar = 42; |
| } |
ES5新增的数组方法彻底改变了数据处理方式:
| var numbers = [1, 2, 3, 4, 5]; |
| |
| |
| var result = numbers |
| .filter(n => n % 2 === 0) |
| .map(n => n * 2) |
| .reduce((sum, n) => sum + n, 0); |
| |
| console.log(result); |
Object.defineProperty开启了元编程的新时代:
| var obj = {}; |
| Object.defineProperty(obj, 'readOnlyProp', { |
| value: 42, |
| writable: false, |
| enumerable: true |
| }); |
| |
| obj.readOnlyProp = 100; |
| console.log(obj.readOnlyProp); |
内置的JSON对象简化了数据交换:
| var data = { |
| name: "Alice", |
| age: 30, |
| skills: ["JavaScript", "Python"] |
| }; |
| |
| var jsonString = JSON.stringify(data); |
| var parsedData = JSON.parse(jsonString); |
bind方法解决了this指向的历史难题:
| var obj = { |
| value: "Hello", |
| show: function() { |
| console.log(this.value); |
| } |
| }; |
| |
| setTimeout(obj.show.bind(obj), 100); |
let/const解决了变量提升问题:
| for (let i = 0; i < 5; i++) { |
| setTimeout(() => console.log(i), 100); |
| } |
| |
| const PI = 3.1415; |
| |
箭头函数改变了this的绑定规则:
| const counter = { |
| count: 0, |
| increment: function() { |
| setInterval(() => { |
| this.count++; |
| console.log(this.count); |
| }, 1000); |
| } |
| }; |
| |
| counter.increment(); |
class关键字带来更清晰的面向对象编程:
| class Animal { |
| constructor(name) { |
| this.name = name; |
| } |
| |
| speak() { |
| console.log(`${this.name} makes a noise.`); |
| } |
| } |
| |
| class Dog extends Animal { |
| speak() { |
| super.speak(); |
| console.log(`${this.name} barks.`); |
| } |
| } |
| |
| const d = new Dog('Rex'); |
| d.speak(); |
ES6模块系统改变了代码组织方式:
| |
| export const PI = 3.14159; |
| |
| export function sum(a, b) { |
| return a + b; |
| } |
| |
| |
| import { PI, sum } from './math.js'; |
| console.log(sum(PI, 2)); |
Promise规范统一了异步处理:
| function fetchData(url) { |
| return new Promise((resolve, reject) => { |
| |
| setTimeout(() => { |
| if (url === 'good') { |
| resolve({ data: 'success' }); |
| } else { |
| reject(new Error('Request failed')); |
| } |
| }, 1000); |
| }); |
| } |
| |
| fetchData('good') |
| .then(response => console.log(response.data)) |
| .catch(error => console.error(error.message)); |
| |
| const person = { name: 'Alice', age: 30 }; |
| const { name: personName, age } = person; |
| console.log(personName); |
| |
| |
| const [first, , third] = [1, 2, 3]; |
| console.log(first, third); |
| |
| |
| function printUser({ name, age = 20 }) { |
| console.log(`${name} is ${age} years old`); |
| } |
| printUser({ name: 'Bob' }); |
| const user = { name: 'Charlie', age: 25 }; |
| console.log(`User ${user.name} |
| is ${user.age > 18 ? 'adult' : 'minor'}`); |
| |
| |
| function currency(strings, ...values) { |
| return strings.reduce((result, str, i) => |
| `${result}${str}${values[i] ? `$${values[i].toFixed(2)}` : ''}`, ''); |
| } |
| |
| const price = 19.99; |
| const tax = 1.99; |
| console.log(currency`Total: ${price + tax}`); |
从ES6开始采用的年度发布周期(ES2016、ES2017等)确保了语言持续进化:
| |
| async function fetchUserData() { |
| try { |
| const response = await fetch('/api/user'); |
| const data = await response.json(); |
| return data; |
| } catch (error) { |
| console.error('Fetch failed:', error); |
| } |
| } |
现代工具链(Babel、Webpack)如何处理新旧语法:
| |
| const user = { |
| name: 'David', |
| age: 35, |
| job: 'Developer' |
| }; |
| |
| const { job = 'Unemployed', ...rest } = user; |
| |
| |
| var _user = user, |
| job = _user.job === void 0 ? 'Unemployed' : _user.job, |
| rest = _objectWithoutProperties(_user, ["job"]); |
TypeScript与JavaScript的协同发展:
| interface User { |
| name: string; |
| age: number; |
| email?: string; |
| } |
| |
| function registerUser(user: User): void { |
| |
| } |
| |
| function Counter() { |
| const [count, setCount] = useState(0); |
| |
| useEffect(() => { |
| document.title = `Count: ${count}`; |
| }, [count]); |
| |
| return ( |
| <div> |
| <p>{count}</p> |
| <button onClick={() => setCount(c => c + 1)}>+</button> |
| </div> |
| ); |
| } |
Node.js的模块系统:
| |
| import { createRequire } from 'module'; |
| const require = createRequire(import.meta.url); |
| |
| const legacyModule = require('./legacy.cjs'); |
现代构建配置示例(webpack.config.js):
| module.exports = { |
| entry: './src/index.js', |
| module: { |
| rules: [ |
| { |
| test: /\.js$/, |
| exclude: /node_modules/, |
| use: { |
| loader: 'babel-loader', |
| options: { |
| presets: ['@babel/preset-env'] |
| } |
| } |
| } |
| ] |
| } |
| }; |
| |
| const parseJSON = (input) => match (input) { |
| when (${String} s) try { JSON.parse(s) } catch { null }, |
| when (${Object} o) => o, |
| else => null |
| }; |
| |
| WebAssembly.instantiateStreaming(fetch('module.wasm')) |
| .then(obj => { |
| const result = obj.instance.exports.add(2, 3); |
| console.log(result); |
| }); |
(正文结束)
微信扫一扫:分享
微信里点“发现”,扫一下
二维码便可将本文分享至朋友圈。