笔记内容多摘录自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);
- };
- };
来源: https://www.cnblogs.com/sunven/p/9446432.html