《JavaScript设计模式与开发实践》读书笔记 一

一本很是值得推荐的书,看了前几章以为收获还挺大的,因而整理成了笔记。本篇博客主要是一到三章的内容,也是书籍所分的第一部分,基础知识,后续内容会尽快更新的。javascript

主要内容:动态类型语言、鸭子类型、this、call、apply、闭包、高阶函数。java

第一章、面向对象的JavaScript

  1. 动态类型语言和鸭子类型
    • 编程语言按照数据类型大致能够分为两类,静态类型语言和动态类型语言
      • 静态类型语言在编译时就能发现类型不匹配的错误,规定了数据类型,编译器还能够对程序进行一些优化,提升程序执行的速度,缺点是会增长更多的代码
      • 动态类型语言的优势是编写的代码数量更少,专一于逻辑表达,缺点是没法保证变量的类型
    • 鸭子类型:关注对象的类型,而不关注对象的自己
    • 根据鸭子类型的思想,咱们没必要借助于超类,就能够轻松的实如今动态类型语言中实现的一个原则:‘面向接口编程,而不是面向实现编程’
  2. 多态
    • 含义:同一操做做用于不一样的对象上面,能够产生不一样的结果
    • 多态背后的思想是将‘作什么’和‘说去作以及怎样作’分离开来,也就是将不变的事物和可能改变的事物分离开来
    • JavaScript对象的多态性是与生俱来的
    • 面向对象设计的优势是将行为分布在各个对象中,并让这些独享负责本身的行为
  3. 封装
    • 封装的目的是将信息隐藏
    • 封装数据只能模拟出public private两种封装性,函数建立做用域,let,经过symbol建立私有属性
    • 封装的实现:封装使得对象内部的变化对其余对象而言是透明的,也就是不可见的,对象对本身的行为负责。其余对象或者用户都不关心它的内部实现,使得对象之间的耦合变松散
    • 封装是静态语言中一种重要的封装方式,通常把对象真正类型隐藏在抽象类和接口以后,相比对象类型,客户更关心对象的行为,促使工厂方法模式,组合模式的产生,javaScript中没有对抽象类和接口进行支持,没有能力进行封装。
  4. 原型模式和基于原型继承的JavaScript对象系统
    • 使用克隆的原型模式
    • 克隆是建立对象的手段
    • 原型编程范型的规则
      • 全部数据都要是对象
      • 要获得一个对象不是经过实例化类,而是找到一个对象做为原型克隆他
      • 对象会记住它的原型
      • 若是对象没法响应某个请求,他会把这个请求委托给本身的原型
    • JavaScript的原型继承
      1. 全部数据都是对象:除了undefined,一切都应是对象。javascript引入两套类型机制,基本类型和对象类型,number,boolean,string数据类型能够经过包装类的方式变成对象数据类型
        • javaScript的根对象是Object.prototype对象,Object.type对象是一个空对象,javascript建立每一个对象,实际都是从它克隆来的
      2. 要获得一个对象,不是经过实例化,而是找到一个对象做为原型并克隆它
        • javaScript中没有类的概念,javaScript函数能够做为普通函数被调用也能够做为构造器被调用,用new运算符来调用时,此时的函数是构造器
        • new运算符建立对象的过程是先克隆Object.prototype对象,再进行其余额外操做(为了性能,并非每次都新克隆对象),过程:先克隆一个对象,取得外部传入的构造器,将对象指向正确的原型,借用外部传入的构造器给obj设置属性,确保是对象并将对象返回
      3. 对象会记住它的原型
        • 仔细的说是记住对象的构造器的原型,把请求委托给构造器的原型
        • __proto__指向该对象的构造器的原型
      4. 若是对象没法响应某个请求,他会把这个请求委托给它的构造器的原型
      //实现一个类继承自另外一个类的效果 var A=function(){} A.prototype={name:'sven'} Var B=function(){} B.prototype=new A() var B=new B() console.log(B.name) 
      1. 原型继承的将来编程

        设计模式是对语言不足的补充,Object.create()是原型模式的自然实现,使用它完成原型继承更能体现原型继承的精髓,可是Object.create()建立对象的效率并不高,比构造函数要慢,经过设置构造器的prototype来实现原型继承的时候,除了跟对象外,任何对象都会有一个原型,而经过Object.create(null)能够建立出没有原型的对象设计模式

  5. 原型模式是一个设计模式,也是一种编程范型,构成了javaScript语言的根本,原型模式十分重要,经过原型模式来实现面向对象系统简单而强大

第二章、this,call,apply

  1. this数组

    • this的指向:
      • 做为对象的方法调用
      • 做为普通函数调用
      • 构造器调用
      • Function.prototype.call或Function.prototype.apply调用
    1. 做为对象的方法调用:this指向该对象
      var obj={ a;1, getA:function(){ alert(this===obj) //true alert(this.a) //1 } } obj.getA(); 
    2. 做为普通函数调用:this不做为对象的属性被调用时,普通函数方式时,此时this总指向全局对象,window
    window.name='globalName' var myObj={ name:'even', getName:function(){ return this.name } } var getName=myObj.getName; console.log(getName()) //globalName 
    1. 构造器调用:javaScript中没有类,可是能够从函数构造器中建立对象,也提供了new,使构造函数更像一个类,构造函数和普通函数的区别就是调用方式,用new运算符调用函数时,该函数总会返回一个对象,构造器里的this就指向返回的这个函数,除非构造器显示地返回了一个object类型的对象

    4.Function.prototype.call或Function.prototype,apply调用浏览器

    丢失的this安全

  2. call和apply闭包

    1. 区别:做用如出一辙,区别仅在于传入参数形式不一样,第一个函数指定了函数体this对象的指向,第二个参数为一个带下标的集合,能够是数组,也能够是类数组,javaScript参数在内部就是一个数组来表示,apply比call的使用率更高,call是包装在apply上面的一层语法糖
    2. 用途:
      1. 改变this指向
      2. Function.prototype.bind
      3. 借用其余对象的方

第三章、闭包和高阶函数

JavaScript是一门面向对象的编程语言,可是这门语言同时也拥有许多函数式语言的特性 函数式语言的鼻祖是LISP,JavaScript之初参考了Scheme 许多设计模式都是用闭包和高阶函数实现的

1.闭包

  1. 变量的做用域:变量的做用域指变量的有效范围,声明变量,若是变量前面没有带var,就是全局变量
var a=1; var fun1=function(){ var b=2; var fun2=function(){ var c=3; alert(b); //2 alert(a); //1 }; fun2(); alert(c); // c is undefined } func1(); 
  1. 变量的生存周期app

    • 对于全局变量,生存周期是永久的,除非主动销毁这个变量,对于由var 声明的局部变量,会随着函数调用的结束而被销毁。】
    var func=function(){ var a=1; return function(){ a++; alert(a); } } var f=func(); f() //2 f() //3 // 由于执行`var f= func()`时,f返回了一个匿名函数的引用,它能够访问到func()被调用时产生的环境,局部变量a一直处于这个环境,因此局部变量a不会被销毁。产生了一个闭包结构 
  2. 闭包的更多做用编程语言

    • 封装变量
      • 闭包能够帮助把一些不须要暴露在全局的变量封装成"私有变量",避免这个变量在其余地方被修改形成错误
      • 提炼函数是代码重构的技巧,经常把可以独立出来的代码封装在独立的小函数里,若是小函数不须要复用,最好用闭包将其封闭起来
    • 延续局部变量的寿命
    var report=(function(){ var imgs=[]; return function(src){ var img=new Image(); imgs.push(img); img.src=src; } })(); //解决请求丢失的问题 
  3. 闭包和面向对象设计

    • 过程与数据的结合是形容面向对象中的“对象”常用的表达
    • 对象以方法的形式包含了过程,闭包是在过程当中以环境的形式包含了数据,一般用面向对象能够实现的功能,闭包也能够实现
  4. 用闭包实现命令模式

    • 命令模式的意图是把请求封装为对象,从而分离请求的发起者和请求的接收者。
    // 
  5. 闭包与内存管理

    • 闭包是一个很是大的特性,但有不少误解
    • 闭包容易形成循环引用,若是此时做用域链中保存着DOM节点,就有可能形成内存泄露,这并非闭包和浏览器的问题,也不是JavaScript的问题,因为BOM和DOM中的对象是使用C++以COM实现,COM对象的垃圾回收机制采用的是引用计数,若是两个对象之间造成了循环引用,那么两个对象就都不能被回收,本质上不是闭包形成的。
    • 解决:把循环引用中的变量设为null,设置为null表示切断与它此前引用的值的联系

2.高阶函数

高阶函数:函数能够做为参数被传递,函数能够做为返回值输出

  1. 函数做为参数传递
    • 回调函数
    • Array.prototype.sort
  2. 函数做为返回值输出
    • 判断数据的类型
    • getSingle
  3. 高阶函数实现AOP(面向切面编程)
    • 面向切面编程的主要做用是把一些跟核心业务无关的功能抽离出来,例如日志统计,安全控制,异常处理等,抽离出来后经过动态织入的方式掺入业务逻辑中,好处是能够保持业务逻辑模块的纯净和高内聚性,其次是能够很方便的复用日志统计等模块儿
  4. 高阶函数的其余应用
    • currying
    • uncurrying
    • 函数节流
    • 分时函数
    • 惰性加载函数

 

注:本篇博客主要内容来自书籍原文

相关文章
相关标签/搜索