ES6(ES2015)的 9 个重要新特性
ECMAScript 是什么?
ECMAScript 是 语言规范,定义: • 语法:变量、函数、作用域、类… • 运行语义:类型系统、原型链、执行上下文、事件循环… • 内建对象:Array、Map、Promise…
JavaScript 与 ECMAScript 的关系 • JavaScript = ECMAScript(核心语言) + 浏览器 API(DOM、BOM、Web APIs)。 • 浏览器与 Node.js 都会“实现 ECMAScript”,也会另外扩展自己的 API。
大版本节点(工程师必记) • ES5 (2009):奠基标准,正式规范化 JS 行为。 • ES6(2015):JavaScript 的“现代化起点”,引入 modules、class、let/const、Promise、箭头函数…之后每年 ES7、ES8 等逐步演进。
JIT(Just-In-Time)性能模型:为什么 JS 能跑这么快?
现代 JavaScript 引擎(V8、SpiderMonkey、JSC)依赖 JIT:
- 找热函数 / 热路径(Hot Function / Hot Path) • hot function:被频繁调用的函数。 • hot path:在循环或分支中被大量重复执行的那条路径。
引擎会盯着代码运行 → 统计哪些地方“热”。
- 类型稳定性(Type Stability)
一段 JS 若“类型不乱变”,JIT 引擎就能假设: • 这个变量一直是 number • 这个数组一直是 packed array(没有 holes) • 这个对象 Shape 没变
- 激进优化(Aggressive Optimization)
一旦引擎觉得“类型稳定”,它会: • 删除所有动态检查(typeof / hidden class 检查等) • 直接生成接近 C 的机器码
结果:几十倍性能提升。
- 反优化(Deopt)
如果类型突然变化,JIT 会撤销优化,退回慢速解释器。
ES6(ES2015)的 9 个重要新特性
- let 和 const 关键字
- 作用域的差别:var 可以是全域、也可以是以函式作为范围,let 与 const 则是以区块作为范围。
- var 可以重复宣告,但是 let 与 const 则不行。
- var 宣告的变数会自动初始化,默认为是 undefined ,但是 let 与 const 则不会。
- let 可以重新赋值 const 不行
- 箭头函式(Arrow Functions)
// ES5 一般函式
let addOne = function (n) {
return n + 1;
};
// ES6 箭头函式,参数只有一个时,参数的括号可以省略
let addOne = (n) => {
return n + 1;
};
// ES6 箭头函式,只有一行时,省略大括号和 return
let addOne = (n) => n + 1;
- this 代表:“这段代码现在是替谁执行的”
- 普通函数的 this 取决于“怎么被调用”:裸调用 f() 时(严格模式)this 是 undefined,通过对象调用 obj.f() 时 this 是 obj,用 f.call(user) 时 this 是 user,用 new F() 时 this 是新建对象;而箭头函数的 this 完全忽略上述调用方式,永远等于它“定义时外层最近的普通函数的 this`。
- 箭头函式不能作为构造函式使用,换言之不能用 new 关键字调用,会报错
样板字面值(Template Literals):样板字面值是被反引号``所封闭
解构赋值(Destructuring Assignment)
const arr = ["iphone", 20000];
const [product, price] = arr;
console.log(product); // iphone
console.log(price); // 20000
- 默认参数(Default Parameters)
// 透过默认参数,确保 a 和 b 有预设值
function add(a = 0, b = 0) {
return a + b;
}
console.log(add(1)); // 1
- 展开运算符(Spread Operator)和其余参数(Rest Parameters)
- 展开运算符,把“可迭代的东西”摊开
const base = { a: 1, b: 2 };
const patch = { b: 3, c: 4 };
const merged = { ...base, ...patch };
// { a:1, b:3, c:4 }
- 收集剩余参数:
const user = { id: 1, name: "Tom", password: "12345" };
const { password, ...publicInfo } = user;
- 类(Classes)
- 什么是class
class Animal {
constructor(name) {
this.name = name;
}
eat() {
console.log(`${this.name} eat food.`);
}
speak() {
console.log(`${this.name} makes a noise.`);
}
}
- class的继承:extends,super(name) 的作用只有一个:在子类构造函数里正确初始化父类(Animal)的实例部分。
class Dog extends Animal{
constructor(name) {
super(name);
}
speak () {
console.log(`${this.name}barks`);
}
}
- static 静态方法:静态方法不能被物件实例继承,只能通过 class 本身调用。
- 可以通过使用前缀 # 来实现 class 的私有领域 (Private fields),包括建立私有的属性或是方法,而私有领域只能在 class 内部使用,外部无法存取。
- 模组化(Modules)
- 前端模块化是为了让 JS 可维护、可依赖、可拆分;打包工具是为了让这些模块能在浏览器顺利运行并兼具性能。
- webpack 就是在你的源码和浏览器之间加一层“构建管线”:把所有资源当成模块解析 → 分析依赖树 → 转成浏览器可执行的 bundle,并做各种优化。
- Promise
- Promise 是一个“一次性状态机”,表示“未来某一刻异步操作的结果”。Promise 控状态,then 传值,catch 捕错,finally 收尾,await 把“值抽出来”。
async function run () {
try {
const result = await new Promise ((resolve,reject) =>
setTimeout(() => (Math.random() > 0.5 ? resolve("ok") : reject ("err")),300)
);
console.log(result);
}
catch (e) {
console.log ("error:",e);
} finally {
console.log("done");
}
}
run();