
一本很是值得推荐的书,看了前几章以为收获还挺大的,因而整理成了笔记。本篇博客主要是一到三章的内容,也是书籍所分的第一部分,基础知识,后续内容会尽快更新的。javascript
主要内容:动态类型语言、鸭子类型、this、call、apply、闭包、高阶函数。java
第一章、面向对象的JavaScript
- 动态类型语言和鸭子类型
- 编程语言按照数据类型大致能够分为两类,静态类型语言和动态类型语言
- 静态类型语言在编译时就能发现类型不匹配的错误,规定了数据类型,编译器还能够对程序进行一些优化,提升程序执行的速度,缺点是会增长更多的代码
- 动态类型语言的优势是编写的代码数量更少,专一于逻辑表达,缺点是没法保证变量的类型
- 鸭子类型:关注对象的类型,而不关注对象的自己
- 根据鸭子类型的思想,咱们没必要借助于超类,就能够轻松的实如今动态类型语言中实现的一个原则:‘面向接口编程,而不是面向实现编程’
- 多态
- 含义:同一操做做用于不一样的对象上面,能够产生不一样的结果
- 多态背后的思想是将‘作什么’和‘说去作以及怎样作’分离开来,也就是将不变的事物和可能改变的事物分离开来
- JavaScript对象的多态性是与生俱来的
- 面向对象设计的优势是将行为分布在各个对象中,并让这些独享负责本身的行为
- 封装
- 封装的目的是将信息隐藏
- 封装数据只能模拟出public private两种封装性,函数建立做用域,let,经过symbol建立私有属性
- 封装的实现:封装使得对象内部的变化对其余对象而言是透明的,也就是不可见的,对象对本身的行为负责。其余对象或者用户都不关心它的内部实现,使得对象之间的耦合变松散
- 封装是静态语言中一种重要的封装方式,通常把对象真正类型隐藏在抽象类和接口以后,相比对象类型,客户更关心对象的行为,促使工厂方法模式,组合模式的产生,javaScript中没有对抽象类和接口进行支持,没有能力进行封装。
- 原型模式和基于原型继承的JavaScript对象系统
- 使用克隆的原型模式
- 克隆是建立对象的手段
- 原型编程范型的规则
- 全部数据都要是对象
- 要获得一个对象不是经过实例化类,而是找到一个对象做为原型克隆他
- 对象会记住它的原型
- 若是对象没法响应某个请求,他会把这个请求委托给本身的原型
- JavaScript的原型继承
- 全部数据都是对象:除了undefined,一切都应是对象。javascript引入两套类型机制,基本类型和对象类型,number,boolean,string数据类型能够经过包装类的方式变成对象数据类型
- javaScript的根对象是Object.prototype对象,Object.type对象是一个空对象,javascript建立每一个对象,实际都是从它克隆来的
- 要获得一个对象,不是经过实例化,而是找到一个对象做为原型并克隆它
- javaScript中没有类的概念,javaScript函数能够做为普通函数被调用也能够做为构造器被调用,用new运算符来调用时,此时的函数是构造器
- new运算符建立对象的过程是先克隆Object.prototype对象,再进行其余额外操做(为了性能,并非每次都新克隆对象),过程:先克隆一个对象,取得外部传入的构造器,将对象指向正确的原型,借用外部传入的构造器给obj设置属性,确保是对象并将对象返回
- 对象会记住它的原型
- 仔细的说是记住对象的构造器的原型,把请求委托给构造器的原型
- __proto__指向该对象的构造器的原型
- 若是对象没法响应某个请求,他会把这个请求委托给它的构造器的原型
-
原型继承的将来编程
设计模式是对语言不足的补充,Object.create()
是原型模式的自然实现,使用它完成原型继承更能体现原型继承的精髓,可是Object.create()
建立对象的效率并不高,比构造函数要慢,经过设置构造器的prototype来实现原型继承的时候,除了跟对象外,任何对象都会有一个原型,而经过Object.create(null)
能够建立出没有原型的对象设计模式
- 原型模式是一个设计模式,也是一种编程范型,构成了javaScript语言的根本,原型模式十分重要,经过原型模式来实现面向对象系统简单而强大
第二章、this,call,apply
-
this数组
- this的指向:
- 做为对象的方法调用
- 做为普通函数调用
- 构造器调用
- Function.prototype.call或Function.prototype.apply调用
- 做为对象的方法调用:this指向该对象
var obj={ a;1, getA:function(){ alert(this===obj)
- 做为普通函数调用:this不做为对象的属性被调用时,普通函数方式时,此时this总指向全局对象,window
window.name='globalName' var myObj={ name:'even', getName:function(){ return this.name } } var getName=myObj.getName; console.log(getName())
- 构造器调用:javaScript中没有类,可是能够从函数构造器中建立对象,也提供了new,使构造函数更像一个类,构造函数和普通函数的区别就是调用方式,用new运算符调用函数时,该函数总会返回一个对象,构造器里的this就指向返回的这个函数,除非构造器显示地返回了一个object类型的对象
4.Function.prototype.call或Function.prototype,apply调用浏览器
丢失的this安全
-
call和apply闭包
- 区别:做用如出一辙,区别仅在于传入参数形式不一样,第一个函数指定了函数体this对象的指向,第二个参数为一个带下标的集合,能够是数组,也能够是类数组,javaScript参数在内部就是一个数组来表示,apply比call的使用率更高,call是包装在apply上面的一层语法糖
- 用途:
- 改变this指向
- Function.prototype.bind
- 借用其余对象的方
第三章、闭包和高阶函数
JavaScript是一门面向对象的编程语言,可是这门语言同时也拥有许多函数式语言的特性 函数式语言的鼻祖是LISP,JavaScript之初参考了Scheme 许多设计模式都是用闭包和高阶函数实现的
1.闭包
- 变量的做用域:变量的做用域指变量的有效范围,声明变量,若是变量前面没有带var,就是全局变量
var a=1; var fun1=function(){ var b=2; var fun2=function(){ var c=3; alert(b);
-
变量的生存周期app
- 对于全局变量,生存周期是永久的,除非主动销毁这个变量,对于由var 声明的局部变量,会随着函数调用的结束而被销毁。】
var func=function(){ var a=1; return function(){ a++; alert(a); } } var f=func(); f()
-
闭包的更多做用编程语言
- 封装变量
- 闭包能够帮助把一些不须要暴露在全局的变量封装成"私有变量",避免这个变量在其余地方被修改形成错误
- 提炼函数是代码重构的技巧,经常把可以独立出来的代码封装在独立的小函数里,若是小函数不须要复用,最好用闭包将其封闭起来
- 延续局部变量的寿命
var report=(function(){ var imgs=[]; return function(src){ var img=new Image(); imgs.push(img); img.src=src; } })();
-
闭包和面向对象设计
- 过程与数据的结合是形容面向对象中的“对象”常用的表达
- 对象以方法的形式包含了过程,闭包是在过程当中以环境的形式包含了数据,一般用面向对象能够实现的功能,闭包也能够实现
-
用闭包实现命令模式
- 命令模式的意图是把请求封装为对象,从而分离请求的发起者和请求的接收者。
-
闭包与内存管理
- 闭包是一个很是大的特性,但有不少误解
- 闭包容易形成循环引用,若是此时做用域链中保存着DOM节点,就有可能形成内存泄露,这并非闭包和浏览器的问题,也不是JavaScript的问题,因为BOM和DOM中的对象是使用C++以COM实现,COM对象的垃圾回收机制采用的是引用计数,若是两个对象之间造成了循环引用,那么两个对象就都不能被回收,本质上不是闭包形成的。
- 解决:把循环引用中的变量设为null,设置为null表示切断与它此前引用的值的联系
2.高阶函数
高阶函数:函数能够做为参数被传递,函数能够做为返回值输出
- 函数做为参数传递
- 回调函数
- Array.prototype.sort
- 函数做为返回值输出
- 高阶函数实现AOP(面向切面编程)
- 面向切面编程的主要做用是把一些跟核心业务无关的功能抽离出来,例如日志统计,安全控制,异常处理等,抽离出来后经过动态织入的方式掺入业务逻辑中,好处是能够保持业务逻辑模块的纯净和高内聚性,其次是能够很方便的复用日志统计等模块儿
- 高阶函数的其余应用
- currying
- uncurrying
- 函数节流
- 分时函数
- 惰性加载函数
注:本篇博客主要内容来自书籍原文