变量与提升
var/let/const、hoisting、strict mode、typeof。
30 分钟
变量与提升
javascript-core 已介绍 let/const;本课深入 hoisting(提升)、TDZ(暂时性死区)、strict mode 与 typeof 的边界行为。Node 与浏览器脚本在 nodejs-essentials 中默认 "use strict" 模块作用域。
学习目标
- 解释
var/let/const在提升与作用域上的差异 - 使用 strict mode 避免静默错误
- 理解
typeof null === 'object'等历史遗留
var 的提升
console.log(a); // undefined(声明被提升,赋值未提升)
var a = 1;
// 等价于:
// var a;
// console.log(a);
// a = 1;
函数声明整体提升:
foo(); // 'ok'
function foo() {
return 'ok';
}
函数表达式(var fn = function(){})只提升变量名,不提升赋值。
let / const 与 TDZ
// console.log(b); // ReferenceError: 在 TDZ 内
let b = 2;
const c = 3;
// c = 4; // TypeError: Assignment to constant variable
let/const 从块开始到声明语句之间处于暂时性死区,访问会抛 ReferenceError。
strict mode
'use strict';
// 禁止未声明变量赋值
// mistyped = 1; // ReferenceError
// 禁止删除不可删属性
// delete Object.prototype; // TypeError
function strictFn(a, a) {} // SyntaxError: 重复参数名
模块(ESM)与 class 体自动 strict;React 组件文件通常继承这一行为。
typeof 与特殊值
typeof undefined; // 'undefined'
typeof null; // 'object'(历史 bug,用 === null 判断)
typeof NaN; // 'number'
typeof function(){}; // 'function'
判断 null 推荐:
const value = null;
value === null; // true
Object.prototype.toString.call(value); // '[object Null]'
块级作用域实战
for (let i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 0); // 0, 1, 2
}
// 若用 var i,则三次都打印 3
react-essentials 中 map 回调里的索引变量,用 let 可避免经典闭包陷阱。