警告
本文内容只在严格模式下适用
声明变量
js
var foo; //声明 foo 变量并初始化为 undefined
关键字 | 作用域 | 重新声明 | 重新赋值 | |
---|---|---|---|---|
var | 全局作用域、函数作用域 | ✔ | ✔ | 全局变量将作为全局对象的属性,且无法被 delete |
let | 块级作用域 | ❌ | ✔ | |
const | 块级作用域 | ❌ | ❌ | 声明时必须指定初始值 |
function | 块级作用域 | ❌ | ✔ | 声明和初始化一起优先提升 |
class | 块级作用域 | ❌ | ✔ | 在类体内作为常量,无法重新赋值 |
变量提升
- 把声明提升至当前作用域顶端,而不提升初始化
- 本质是在编译阶段将变量放入内存中,也就是告诉编译器需要创建哪些变量
- 所有变量声明的初始值为
undefined
暂时性死区
let
、const
、class
声明的变量,在初始化前访问会报 ReferenceError
。
js
(function (foo) {
if (foo) {
let foo = foo + 55;
// ^ ReferenceError
}
for (let foo of foo) {
// ^ ReferenceError
foo;
}
})(33);
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/let#暂时性死区
数据类型
https://tc39.es/ecma262/#sec-ecmascript-data-types-and-values
- 原始值
- Null
- Undefined
- Boolean
- Number
- BigInt
- String
- Symbol
- Object
原型链
垃圾回收
引用计数
记录数据被引用的次数,如果没有引用则被回收。 但是无法处理循环引用的情况,因为循环引用将导致 2 个数据的引用次数至少为 1,进而无法被回收导致内存泄漏。
标记清除
定期从根对象开始,递归地查找引用的对象。把找到的对象标记为不清除,并回收找不到的对象。
代码规范
https://github.com/beginor/clean-code-javascript
闭包
柯里化
js
function curry(fn, bindArgs = []) {
const length = fn.length;
return function (arg) {
newArgs = bindArgs.concat(arg);
if (newArgs.length < length) {
return curry.apply(this, [fn, ...newArgs]);
} else {
return fn.apply(this, newArgs);
}
};
}
WeakMap
WeakMap
的键只能为对象WeakMap
对键采取弱引用,即不会影响键的垃圾回收WeakMap
无法对键进行迭代