若是你能看懂如下两张图, 那就能够跳过本总结了, 固然, 点个赞再走啊喂! (#`O′)! es6


啊喂分割线 (#`O′)! (#`O′)! (#`O′)! (#`O′)! (#`O′)! (#`O′)! (#`O′)! (#`O′)! (#`O′)!
你不知道的JavaScript(上册)
做用域和闭包
- LHS和RHS查询, 能够理解为查找变量赋值的目标和源头, 固然, "赋值"能够是隐晦的
- LHS查询失败, 将在严格模式下致使抛出RefrenceError, 非严格模式下则会自动建立新变量
- eval额with分别是修改原有做用域和根据参数建立一个新的做用域
- 咱们若是把函数理解成代码片断之间的接口?
- for循环中的var会污染上级做用域 -> var会污染上级做用域 -> js(es5)没有块级做用域? -> 经过IIFE能够假装一个块级做用域(但这种方法并不普适), 其实with和catch能够建立一个块级做用域 -> js(es5)有块级做用域, 更别说es6了
- 某个函数拥有上级(或上多级)做用域的引用, 就叫作闭包, 详细一点说明就是: 当函数记住并访问其所在的词法做用域, 即使它是在当前词法做用域以外执行, 这就产生了闭包. 闭包可使得函数就访问定义时的词法做用域, 实际上只要使用了回调函数就使用了闭包
- 模块的两个主要特征: 为建立内部做用域而封装了包装函数; 包装函数的返回值必须包括一个内部函数的引用;
- JS只有词法做用域(定义在书写代码使得做用域, 固然排除eval和with)
- 词法做用域关注函数在何处声名, 动态做用域关注函数在何处调用
- bind函数常常用于替代匿名的箭头函数, 以建立具名函数
this和对象原型
- 想比较于显式传入上下文对象, this关键字使用了一种更佳优雅的方式, 传递一个对象的引用
- this不指向(或不只仅指向)函数自己或者函数的做用域, 他是在函数建立(调用)时被绑定的
- 在非严格模式中, 直接调用函数, 一般会自动将this绑定到全局对象, 称之默认绑定
- 隐式绑定即判断调用函数时的上下文对象, 如 obj.say(), 将say中的this隐式绑定到obj
- 显式绑定即call, apply, 其中一种特殊的形式叫作硬绑定, bind
- 使用new将会发生以下步骤: 建立新对象, 设置__proto__为函数的prototype, 绑定this到新对象, 默认返回这个新对象(最后这一点常被认为是new的一个反作用)
- 给bing, call等函数传入null, undefined将出乎意料的致使this绑定到全局对象, 更安全的解决办法是使用一个空对象, 如Object.create(null)
- JS中基本类型自己不是对象, 只是建立时字面量会自动被转化为对象, typeof null === 'object' 的结果是bug
- 对象键访问会将其中的值转化为字符串, 就算是数字也不例外, 然而数组反之
- 经过遍历对象属性进行freeze能够模拟"深度冻结", 可是可能在无心中冻结其它(共享)对象
- hasOwnProperty只检查自身属性, 而in操做符会搜索至原型链
- 4 in [1,2,4] 可能不会获得你想要的结果 --- 答案是false, 由于in操做符检查的是属性名
- 类/继承描述了代码的一种组织结构方式->软件对真实世界问题领域的建模方法
- 多态指父类的通用行为能够被子类用更特殊的行为重写
- JS中利用显示伪多态(Car子类调用Vehicle.drive.call(this)), 将极大增长维护成本, 代码复杂度, 应尽可能避免使用, 或者改成将父类方法保存到子类中
- 总的来讲, 在JS中模拟类是得不偿失的
- 属性的屏蔽比想象中的要复杂, 若是底层对象没有该属性, 则上层对象的属性的writable:false或是其做为setter存在, 会对赋值(=)操做有影响, 固然你可使用defineProperty来解除这种影响. 这里有个坑, 如a.b++其实至关于a.b=a.b+1
- 继承意味着"复制操做", JS中经过prototype实现的继承, 将只是建立对象之间的关联, 而不是复制操做
- JS中"构造函数"的概念仅存在于使用new操做符时, new将普通函数劫持, 将调用变成有返回值的"构造函数调用"
- JS中.constructor属性与"构造"毫无关系, 把他当成一个普通的属性理解就好
- JS原型继承(B.prototype= Object.create(A.prototype))能够类比为"类的继承"
- Object.create修改[[Prototype]]以修改对象之间的链接关系, 这和new是同样的, 可是, new还会经过Base.call(newObj)作一些其余事
- 空的对象(__proto__==null)叫作"字典", 由于没有任何委托, 因此适合用来储存数据
- 总的来讲, 用"委托"来描述JS对象之间的关联关系(OLOO)更合适(而不是"复制")
- 类风格代码(Function,new或是ES6的Class)强调实体和实体的关系, OLOO则只关注对象关联关系, 这里有两张图太棒了, 惋惜放不出来
- 鸭子类型(if(a.b)a.b())有时比instanceof有效