我觉得可以谈论一些对象有关的东西,就这些会比较复杂。
另外一些,其实是 ==
和 ===
,由于一些历史原因,这里似乎存在不少的坑,后续会写一个专栏,来详细填一下。
- obj 本身是不含有
this
的,但是若是在里面包含函数,则可以使用 this
,并且是在调用时确认的,这就会有一些有趣的写法。
- obj 是 pass by ref 的,所以得要有 clone 才行。
- obj 的 key 可以是 String 和 Symbol。
- 除了可以用 class 构建类,用
new Func
使用构造函数构建也不错。
- 内建的一些 Symbol 可以用来实现一些内建的功能,类似于实现某种接口。比如说实现 iterator,用来给
for..of
使用。
- 原始类型(String, Number, etc.)会用一种特殊的 wrapper 来实现「方法调用」,其在调用方法时,js 规定先将其转换成其对应的包装类,施加对应方法的操作后,再返回原始类型(Primitives)。
- Array 是一个 Object 而非 Primitives。
- array-like 是个特殊的 obj,只要有 index 和 length 就成立,内置的一些方法对其有效。String 就是一种 array-like。Symbol.iterator 不和 array-like 绑定。
- 会有一些内建对象:
- Array(连续内存,顺序表),
- Map(相比于 obj,key 可以是任意类型,特别是将 obj 作为key,相比于 obj 自身,他会将任何东西都转化成 String(调用
tostring
),此外 Map 是 Chaining 的,顺序也是保留的)
- 有两个比较特别的:WeakMap 和 WeakSet,与垃圾回收有关,他们不会保存 key 的引用,可以充当 cache 使用。
- Destructuring 是个糖,类似 py 里的 tuple,还有个 trick 可以做 swap,还可以有 default value。所以当然可以用作函数传参和返回值。
- 引擎先扫描变量,并记录下来,如果在声明(
let
)前使用,则会出现 undefined,而非「不存在」,当执行到 let 后,才变得可用,在这之前的这段区域称为:dead zone。
for
on each iteration generates a new lexical environment。
- closure 也可以用函数的属性来替代,closure 的优势在于可以隐藏属性。我觉得面向对象和函数式编程可能会导致选择摇摆不定,
- Named Function Expression,对于本身是表达式的时候在需要递归的时候还是挺好用的。当你想要在 Function Expression 中使用函数名(递归…)时,最好考虑使用 Named 的版本,方便后续的函数赋值操作。
- The "new Function" syntax
new Function
就是用来整序列化的活的。创造出来的新函数的 [[Environment]]
为 Global,尽量不使用外部变量是设计该函数的原则,因此,尽量使用 parameters 来构造吧。
- Decorators and forwarding, call/apply
- 装饰器么,注意如果传入的是一个对象的方法的时候,要用
func.call
或者 func.apply
改写。
- 当 array-like 用不了某些 array 的函数时,Borrowing a method 是一个不错的解决方案,例如使用
[].method.call()
。
- 可以用在一些延迟 update 上面,练习部分的题目很是精彩。
- Throttle-decorator 这题目真难,但确实值得思考。
- Function binding
- 多用用 partial bind 吧,可以让代码更清楚。
bind
只能用一次,不能 re-bound。