笔记内容多摘录自《JavaScript设计模式与开发实践》(曾探著),侵删。

面向对象的JavaScript

1. 动态需要类型和鸭子类型

  • 鸭子类型 如果它走起路来像鸭子,叫起来也是鸭子,那么它就是鸭子
  • 只关注对象的行为,而不关注对象本身,也就是关注has-a,而不是is-a
  • 面向接口编程而不是面向实现编程

2. 多态

同一操作作用于不同的对象上,可以产生不同的解释和不同的执行结果。

多态背后的思想是将“做什么”和“谁去做”以及“怎么做”分离开来,也就是将“不变的事物”与“可能改变的事物分离开”

3. 封装

封装的目的是将信息隐藏

4. 原型模式和基于原型继承的JavaScript对象系统

Object.create = Object.create || function( obj ){
var F = function(){};
F.prototype = obj;
return new F();
}
  • 所有的数据都是对象
  • 要得到一个对象,不是通过实例化类,而是找到一个对象作为原型并克隆它
  • 对象会记住它的原型
  • 如果对象无法响应某个请求,它会把这个请求委托给它的构造器的原型

this、call、apply

this

this的指向

  • 作为对象的方法调用
  • 作为普通函数调用
  • 构造器调用
  • Function.prototype.call或Function.prototype.apply调用

call和apply

用途

  • 改变this指向
  • Function.prototype.bind
  • 借用其他对象的方法

闭包和高阶函数

闭包

变量的作用域

变量的生命周期

闭包的作用

  • 封装变量
  • 延续局部变量的寿命

闭包和面向对象设计

用闭包实现命名模式

把请求封装为对象,分离请求发起者和接收者(执行者)之间的耦合关系

var Tv = {
open: function () {
console.log('打开电视机');
}, close: function () {
console.log('关上电视机');
}
}; var createCommand = function (receiver) {
var execute = function () {
return receiver.open(); // 执行命令,打开电视机
}
var undo = function () {
return receiver.close(); // 执行命令,关闭电视机
}
return {
execute: execute,
undo: undo
}
}; var setCommand = function (command) {
document.getElementById('execute').onclick = function () {
command.execute(); // 输出:打开电视机
}
document.getElementById('undo').onclick = function () {
command.undo(); // 输出:关闭电视机
}
}; setCommand(createCommand(Tv));

命令的接收着封闭在闭包中

闭包与内存管理

  • 误解:内存泄漏

高阶函数

函数作为参数传递

  • 回调函数
  • Array.prototype.sort

函数作为返回值输出

  • 判断数据类型
  • getSingle

高阶函数实现AOP

高阶函数的其他应用

1. currying

函数柯里化、部分求值

var currying = function (fn) {
var args = [];
return function () {
if (arguments.length === 0) {
return fn.apply(this, args);
} else {
[].push.apply(args, arguments);
return arguments.callee;
}
}
};
var cost = (function () {
var money = 0;
return function () {
for (var i = 0, l = arguments.length; i < l; i++) {
money += arguments[i];
}
return money;
}
})(); var cost = currying(cost); // 转化成currying 函数
cost(100); // 未真正求值
cost(200); // 未真正求值
cost(300); // 未真正求值
alert(cost()); // 求值并输出:600
2. uncurrying

泛化this的提取过程

Function.prototype.uncurrying = function () {
var self = this;
return function () {
var obj = Array.prototype.shift.call(arguments);
return self.apply(obj, arguments);
};
};
Function.prototype.uncurrying = function () {
var self = this;
return function () {
return Function.prototype.call.apply(self, arguments);
}
};
3. 函数节流
var throttle = function (fn, interval) {
var __self = fn, // 保存需要被延迟执行的函数引用
timer, // 定时器
firstTime = true; // 是否是第一次调用
return function () {
var args = arguments,
__me = this;
if (firstTime) { // 如果是第一次调用,不需延迟执行
__self.apply(__me, args);
return firstTime = false;
}
if (timer) { // 如果定时器还在,说明前一次延迟执行还没有完成
return false; timer = setTimeout(function () { // 延迟一段时间执行
clearTimeout(timer);
timer = null;
__self.apply(__me, args);
}, interval || 500);
};
}
};
4. 分时函数
var timeChunk = function (ary, fn, count) {
var obj,
t;
var len = ary.length;
var start = function () {
for (var i = 0; i < Math.min(count || 1, ary.length); i++) {
var obj = ary.shift();
fn(obj);
}
};
return function () {
t = setInterval(function () {
if (ary.length === 0) { // 如果全部节点都已经被创建好
return clearInterval(t);
}
start();
}, 200); // 分批执行的时间间隔,也可以用参数的形式传入
};
}; var ary = [];
for (var i = 1; i <= 1000; i++) {
ary.push(i);
};
var renderFriendList = timeChunk(ary, function (n) {
var div = document.createElement('div');
div.innerHTML = n;
document.body.appendChild(div);
}, 8);
renderFriendList();
5. 惰性加载函数
var addEvent = function (elem, type, handler) {
if (window.addEventListener) {
addEvent = function (elem, type, handler) {
elem.addEventListener(type, handler, false);
}
} else if (window.attachEvent) {
addEvent = function (elem, type, handler) {
elem.attachEvent('on' + type, handler);
}
}
addEvent(elem, type, handler);
}; var div = document.getElementById('div1');
addEvent(div, 'click', function () {
alert(1);
});
addEvent(div, 'click', function () {
alert(2);
});
6. 函数防抖
var debounce = function (method, delay) {
var timer = null;
return function () {
var _this = this;
var args = arguments;
clearTimeout(timer);
timer = setTimeout(function () {
method.apply(_this, args);
}, delay);
};
};

《JavaScript设计模式与开发实践》读书笔记-基础知识的更多相关文章

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

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

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

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

  3. Javascript设计模式与开发实践读书笔记(1-3章)

    第一章 面向对象的Javascript 1.1 多态在面向对象设计中的应用   多态最根本好处在于,你不必询问对象“你是什么类型”而后根据得到的答案调用对象的某个行为--你只管调用行为就好,剩下的一切 ...

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

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. (十一)c#Winform自定义控件-列表

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...

  2. Lasso估计论文学习笔记(一)

    最近课程作业让阅读了这篇经典的论文,写篇学习笔记. 主要是对论文前半部分Lasso思想的理解,后面实验以及参数估计部分没有怎么写,中间有错误希望能提醒一下,新手原谅一下. 1.整体思路 作者提出了一种 ...

  3. JSON格式提取相同属性的某个值

    [ {UID:"222",value:"111"}, {UID:"222",value:"103"}, {UID:&qu ...

  4. CSS文本超出用省略号代替的方法

    { white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }

  5. C#开发BIMFACE系列5 服务端API之文件直传

    BIMFACE使用了分布式对象存储来存储用户上传的模型/图纸文件.如使用普通的文件上传接口, 文件流会通过BIMFACE的服务器,再流向最终的分布式存储系统,整个上传过程会受BIMFACE服务器的带宽 ...

  6. MSIL实用指南-struct的生成和操作

    struct(结构)是一种值类型,用于将一组相关的信息变量组织为一个单一的变量实体.所有的结构都继承自System.ValueType类,因此是一种值类型,也就是说,struct实例分配在线程的堆栈( ...

  7. Spring框架介绍及使用(转载)

    原文链接 Spring框架—控制反转(IOC) 1 Spring框架概述1.1 什么是SpringSpring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod ...

  8. JIRA中的核心概念

    转载自:http://blog.csdn.net/zhengxy2011/article/details/6940380 1.1.1   问题 JIRA跟踪问题(Issue),这些问题可以是bug,功 ...

  9. P2774 方格取数问题 网络最大流 割

    P2774 方格取数问题:https://www.luogu.org/problemnew/show/P2774 题意: 给定一个矩阵,取出不相邻的数字,使得数字的和最大. 思路: 可以把方格分成两个 ...

  10. poj 1062 昂贵的聘礼(floyd path的应用)

    题目链接:http://poj.org/problem?id=1062 题意就不解释了中问题. 这题用dfs也行.但是感觉还是floyd比较好一点主要是他们交易是有条件的交易总的等级差不能超过m 所以 ...