第一章 面向对象的Javascript

1.1 多态在面向对象设计中的应用  

多态最根本好处在于,你不必询问对象“你是什么类型”而后根据得到的答案调用对象的某个行为--你只管调用行为就好,剩下的一切多态会搞定

换句话说就是:多态的最根本作用就是把过程化的条件分支语句转化为对象的多态性,从而消除这些条件分支语句

例子:假设有一个地图应用,每个地图API提供商都提供了show方法,负责在页面上显示地图,首先我们用一些分支条件语句来实现一个调用方法renderMap

此时一旦需要增加搜搜地图的应用,就必须改动renderMap函数,继续在里面堆砌分支条件语句

我们必须将程序中相同的部分抽象出来,那就是显示整个地图

那么此时,即使以后增加了搜搜地图,renderMap也不需要做什么改变

1.2 对象会记住它的原型

就Javascript的真正实现来说,不能说对象有原型,而只能说对象的构造器有原型,对“对象把请求委托给它自己的原型”这句话, 更好的说法是对象把请求委托给它的构造器原型,

javascript对象通过一个名为_proto_的隐藏属性,来将请求转交给它的构造器,对象的_proto_会指向的它的构造器对象,实际上,_proto_就是对象跟“对象构造器原型”联系起来的纽带

1.3 如果对象无法响应请求,会把请求委托给它的构造器原型

当对象需要a需要借用对象b的能力时,可以选择性的把对象a的构造器的原型指向对象b,从而达到继承的目的

  • 首先,尝试遍历对象a的所有属性,没有找到name这个属性
  • 查找name属性的这个请求被委托给对象a的构造器原型,它被a._proto_记录着并且指向A.prototype,而A.prototype指向obj.
  • 在对象obj中找到了name属性,并返回了它的值

当我们期望得到一个“类”继承自另外一个“类"的效果时,往往会使用下面的方式

第二章 this、call和apply

2.1 this的指向 

this的指向大致可以分为以下4种:

  • 作为对象的方法调用
  • 作为普通函数调用
  • 构造器调用
  • Function.prototype.call或Function.prototype.apply调用(动态的改编传入函数的this)

例子:在div节点事件函数内部,有一个局部的callback方法,callback在调用时,内部的this会指向window

而我们想让它指向div节点,可以用一个变量保存div节点的引用

2.2 call和apply的区别

apply接受两个参数,第一个参数指定了函数体内的this对象的指向,第二个参数为一个带下标的集合,可以为数组,也可以是类数组,apply方法将这个集合中的元素作为参数传递给被调用的函数

call传入的参数不固定,第一个也是代表函数体内this的指向,第二个参数开始,每个参数依次被传入函数

javascript不计较形参实参和顺序上的区别,javascript内部的参数就是用一个数组来表示的,所以apply使用的更频繁一点,我们不必关心具体有多少个参数要传入给函数,只需要一股脑的推过去就好了

如果我们明确知道函数接受多少个参数,而且想一目了然的表达形参和实参的关系,那么也可以用call来传送参数

第三章 闭包和高阶函数

3.1 变量的生命周期

假设页面上有5个div节点,我们通过循环来给每个div绑定onclick事件,按照索引顺序,点击第一个div时弹出0,点击第二个div时弹出1,依次类推,代码如下:

但由于onclick是异步出发,当事件触发时,for循环早已结束,此时i已经是5,所以输出一直是5,解决方法是把每次循环的i封闭起来,当在事件函数中顺着作用于链从内到外查找i时,会先找到被封闭在闭包环境中的i

3.2 封装变量

把一些不需要暴露在全局的变量封装成私有变量,即封闭在函数内部, 减少页面中的全局变量

封闭在函数内部的变量或函数,只会在初始化闭包函数的时候执行一次,以后每一次调用函数,将不再执行封闭在函数内部的代码,这也是闭包的一大好处

3.3 闭包和面向对象设计

通常面向对象能实现的思想,用闭包也能实现,先来看看跟闭包相关的代码:

如果换成面向对象的写法,就是:

3.4 高阶函数

高阶函数是指至少满足下列条件之一的函数:

  • 函数作为参数被传递
  • 函数作为返回值输出

1 函数作为参数被传递

将一些难以复用的代码提取出来,用回调函数的形式传入处理函数,如

Array.prototype.sort的使用可以看到,我们的目的是对数组进行排序,这是不变的部分,而使用什么规则去排序,这是可变的部分,把可变的部分封装在函数参数里,动态传入

3.5 函数柯里化(function currying)

currying 又称部分求值,一个currying首先会接受一个参数,接受这个参数之后,并不会马上求值,而是继续返回另外一个函数,刚才传入的参数在函数形成的闭包中被保存起来,待到函数被真正需要求值的时候,之前传入的所有参数都会一次性求值

首先来看下一种currying函数的实现,方便了解其思想

再来看一个通用的function currying() {} ,function currying() {}接受一个参数,即将要被currying的函数

3.6 函数节流

假设一个函数被触发的概率非常高,就需要采取一些函数节流的方式实现

3.7 分时函数

有些函数需要用户主动调用,但因为一些客观原因,这些函数会严重影响页面性能,比如说我们要在短时间内要往页面中大量加载DOM节点,处理这一类问题的解决方案就是使用timeChunk函数让创建节点的工作分批进行,比如1秒创建1000个节点,改为每200毫秒创建8个节点

timeChunk函数接受3个参数,第一个参数是创建节点所用到的数据,第二个参数是创建节点逻辑的函数,第三个参数表示每一批创建的节点数量

3.8 惰性加载函数

比如我们需要一个要在浏览器中绑定时间的addEvent函数

这个函数的缺点就是,当它每次被调用的时候都会执行里面的if条件分支语句

第二种方案就是,在代码加载的时候执行一次判断,以便让addEvent包裹正确逻辑的函数,代码如下

但目前这个函数还是有一个缺点,假设我们从头到尾都没有使用过addEvent函数呢?

第三种方案就是所使用的惰性加载方案,在第一次进入条件分支的时候,在函数内部会重写这个函数,重写之后的函数就是我们期望的addEvent函数,在下一次进入addEvent函数的时候,addEvent就不存在那些分支判断

Javascript设计模式与开发实践读书笔记(1-3章)的更多相关文章

  1. JavaScript设计模式与开发实践——读书笔记1.高阶函数(上)

    说来惭愧,4个多月未更新了.4月份以后就开始忙起来了,论文.毕设.毕业旅行等七七八八的事情占据了很多时间,毕业之后开始忙碌的工作,这期间一直想写博客,但是一直没能静下心写.这段时间在看<Java ...

  2. JavaScript设计模式与开发实践——读书笔记1.高阶函数(下)

    上部分主要介绍高阶函数的常见形式,本部分将着重介绍高阶函数的高级应用. 1.currying currying指的是函数柯里化,又称部分求值.一个currying的函数会先接受一些参数,但不立即求值, ...

  3. javascript设计模式与开发实践阅读笔记(8)——观察者模式

    发布-订阅模式,也叫观察者模式:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知. 在JavaScript开发中,我们一般用事件模型来替代传统的观察者模式. ...

  4. javascript设计模式与开发实践阅读笔记(7)——迭代器模式

    迭代器模式:指提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示. 迭代器模式可以把迭代的过程从业务逻辑中分离出来,在使用迭代器模式之后,即使不关心对象的内部构造,也可以按顺 ...

  5. javascript设计模式与开发实践阅读笔记(6)——代理模式

    代理模式:是为一个对象提供一个代用品或占位符,以便控制对它的访问. 代理模式的关键是,当客户不方便直接访问一个对象或者不满足需要的时候,提供一个替身对象来控制对这个对象的访问,客户实际上访问的是替身对 ...

  6. javascript设计模式与开发实践阅读笔记(4)——单例模式

    定义 单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点. 具体来说,就是保证有些对象有且只有一个,比如线程池.全局缓存.浏览器中的window 对象等.在js中单例模式用途很广,比如登录 ...

  7. 《JavaScript设计模式与开发实践》笔记第八章 发布-订阅模式

    第八章 发布-订阅模式 发布-订阅模式描述 发布-订阅模式又叫观察者模式,它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知. 发布-订阅模式可以广泛应用于 ...

  8. 《JavaScript设计模式与开发实践》笔记第一章

    第一章 面向对象的JavaScript 动态类型语言和鸭子类型 编程语言按照数据类型大体可以分为两类:静态类型语言.动态类型语言. 静态类型语言:在编译时便已确定变量的类型. 优点: 在编译时就能发现 ...

  9. javascript设计模式与开发实践阅读笔记(5)——策略模式

    策略模式:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换. 我的理解就是把各种方法封装成函数,同时存在一个可以调用这些方法的公共函数.这样做的好处是可以消化掉内部的分支判断,使代码效率 ...

随机推荐

  1. 将Excel数据表到数据库表

    假设你有大量的数据要导入到数据库表,恐怕是没有效率的写程序,作为用于数据操纵,Excel在这方面有优势,但是,如何将其结合起来?将Excel数据表到数据库表,就是本篇博客的目的. 首先去下载MySQL ...

  2. Array of Objects

    You should be comfortable with the content in the modules up to and including the module "Array ...

  3. Linux下 目录 压缩 解压缩 打包

    http://blog.sina.com.cn/s/blog_7479f7990100zwkp.html tar -zcvf /home/xahot.tar.gz /xahot    tar -zcv ...

  4. Swift语言教程中文文档

    Swift语言教程中文文档 Swift语言教程(一)基础数据类型 Swift语言教程(二)基础数据类型 Swift语言教程(三)集合类型 Swift语言教程(四) 集合类型 Swift语言教程(五)控 ...

  5. ovs处理openflow消息的流程

    OVS处理各个openflow消息的详细代码在 ofproto/ofproto.c 中: static enum ofperr handle_openflow__(struct ofconn *ofc ...

  6. POJ 2485 Highways (prim最小生成树)

    对于终于生成的最小生成树中最长边所连接的两点来说 不存在更短的边使得该两点以不论什么方式联通 对于本题来说 最小生成树中的最长边的边长就是使整个图联通的最长边的边长 由此可知仅仅要对给出城市所抽象出的 ...

  7. 阿里游戏大数据sesson2_RF&amp;GBRT(上)

    ----------一个小的游戏体验,对于不太熟悉Xlab RF和GBRT同学们都叫参考,不喜勿喷,大神绕道,米姆达. . .. .---------- 6月初的时候LR 做到4.9后一直上不去,看群 ...

  8. GUIForDebug

    package gui; import org.luaj.vm2.Globals; import org.luaj.vm2.LuaValue; import org.luaj.vm2.ast.Chun ...

  9. 【Linux探索之旅】第二部分第一课:终端Terminal,好戏上场

    内容简介 1.第二部分第一课:终端Terminal,好戏上场 2.第二部分第二课预告:命令行,世界尽在掌握 终端Terminal,好戏上场 随着第一部分的结束,我们进入了第二部分(小编你这好像是废话. ...

  10. Java读取图像和网络存储

    该公司最近在搞一个Web工程,需要下载网络图片,那么既然恢复了一些最基本的东西.数据传输不同的流,简单,很容易下载网络打破了样品的图片,代码非常easy.贡献给大家! 结论,图片主要就四步: 1:拿到 ...