同一操作作用于不同的对象上面,可以产生不同的解释和不同的执行结果。
AnimalSound
实现多态,需要写一个 Animal
类来让子类继承,其实只是为了解决类型的问题。JavaScript 因为其动态性就完全不存在这种问题。多态的最根本好处在于,你不必再向对象询问“你是什么类型”而后根据得到的答案调用对象的某个行为 ---《重构: 改善既有代码的设计》
renderMap
会根据 type
值去渲染谷歌地图或者百度地图,但是如果又增加了其他地图,则必须改动 renderMap
中的代码,这就违反了「开闭原则」,即 软件中的对象(类,模块,函数等等)应该对于扩展是开放的,但是对于修改是封闭的。而且参数还是一些魔法字符串,很容易写错。renderMap
命令时自己应该知道该干什么,我们改写 renderMap
如下。将信息隐藏
在以类为中心的面向对象编程语言中,类和对象的关系可以想象成铸模和铸件的关系,对象总是从类中创建而来。而在原型编程的思想中,类并不是必须的,一个对象是通过克隆另外一个对象所得到的
Object.prototype
,它是一个空对象,我们在 JavaScript 中遇到的每个对象,实际上都是从 Object.prototype
中克隆出来的。Object.prototype
对象就是它们的原型。new
运算符来调用此函数,此函数就是一个构造器。new
的实现如下「currying」又称部分求值。一个 currying 的函数首先会接受一些参数,接受这些参数后,该函数不会立即根据参数求值,而是继续返回一个函数,刚才传入的参数在函数形成的闭包中被保存起来,等到函数真正被需要求值的时候,之前传入的参数都会被用于最后的求值
「unCurrying」反柯里化函数,从字面讲,意义和用法跟函数柯里化相比正好相反,扩大适用范围,创建一个应用范围更广的函数。使得本来只有特定对象才适用的方法,扩展到更多的对象。
self
就是 Array.prototype.push
, 返回的内容可以写成 a.apply(b, params)
其实就是 b.a(param1, param2, ..)
所以就等同于push(obj, 2)
其实就是Array.prototype.push.call
onChange
事件都要去拿到 value
去调用 API 查看是否重复。因为用户每次敲击键盘都会触发 onChange
,所以在用户输入的过程中也会频繁的去调用 API,但此时都是无意义的检测,因为用户根本想要的不是之前的姓名。所以我们可以在用户停止输入一段时间后再去调用 API。wait
为 3s,当连续触发10 秒时,它会执行四次,分别是 0、3、6、9 秒,9 到 10 秒之间也在进行操作,但是并不能执行事件。第二种方式的缺点不会立马执行,优点就是当连续触发 10 秒时,它会在 3、6、9、12 秒的时候执行事件,因为在 9 秒过后就会触发并生成三秒后触发事件的定时器。scrollTop
,如果只获得 9 秒时的 scrollTop
, 显然是不对的,因为 9 到 10 秒还是触发了滚动事件。但我们获得 12 秒时的 scrollTop
时,就肯定是正确的,因为滚动事件早在 10 秒时已经停止了。wait
秒时(因为 previous
默认为 0 ,所以第一次时也满足此种情况),立即执行函数,并设置 previous
为当前时间;当距离上次触发时间小于 wait
秒时,首先检查是否有 timer
如果没有的话就创建定时器,时间为距离下次触发函数的时间,然后设置 previous
为定时器结束后的时间,并在定时器结束后清空定时器。如果有 timer
,就不做任何事情。