js设计模式基础
2017-10-22 14:59
288 查看
1. 多态
多态的实际含义是:同一操作作用于不同的对象上面,可以产生不同的解释和不同的结果。var sayName = function( obj ){ obj.prototype.sayname.call(obj); } var Animal = function(){}; Animal.prototype.sayname = function(){ console.log( this.name ); } var duck = { name:"duck" } duck.prototype = new Animal; var chick = { name:"chick" } chick.prototype = new Animal; sayName(duck); // duck sayName(chick);//chick
上面的例子很清楚的说明了 多态 和继承 以及原型模式,这只是一个很简单的例子
2.call this apply
1.this 使用方法 对象方法调用 普通函数调用 构造器调用Function.prototpe.call和
Function.prototype.apply调用(
this指向,类数组的参数)若第一个为
null则默认为宿主对象
var obj = { a: 1, getA: function(){ console.log( this === obj ); console.log( this.a ); } }; obj.getA(); this.name = 'pi'; var obj = { name: 'seven', getname: function(){ return this.name; } }; var getName = obj.getname; console.log( getName() ); var MyClass = function(){ this.name = 'sven'; return 'pipi' }; var obj = new MyClass(); console.log ( obj.name ); // 输出:anne var obj1 = { name: 'sven', getName: fun d5ef ction(){ return this.name; } }; var obj2 = { name: 'anne' }; console.log( obj1.getName() ); // 输出: sven console.log( obj1.getName.call( obj2 ) ); // 输出:anne var obj = { myName: 'sven', getName: function(){ return this.myName; } }; console.log( obj.getName() ); // 输出:'sven' var getName2 = obj.getName; //普通函数 this指向全局 console.log( getName2() ); // 输出:undefined //丢失的this
2.call和apply用途(区别,call是一个个传参数而 apply是数组传参)
1.改变this的指向
2.bind指定函数内部this的指向
Function.prototype.bind = function() { var self = this, // 保存原函数 context = [].shift.call(arguments), // 需要绑定的 this 上下文 args = [].slice.call(arguments); // 剩余的参数转成数组 return function() { // 返回一个新的函数 return self.apply(context, [].concat.call(args, [].slice.call(arguments))); // 执行新的函数的时候,会把之前传入的 context 当作新函数体内的 this // 并且组合两次分别传入的参数,作为新函数的参数 } };
var obj = { name: 'sven' }; var func = function(a, b, c, d) { console.log(this.name); // 输出:sven console.log([a, b, c, d]) // 输出:[ 1, 2, 3, 4 ] }.bind(obj, 1, 2); func(3, 4); var A = function(name) { this.name = name; }; var B = function() { A.apply(this, arguments); }; B.prototype.getName = function() { return this.name; }; var b = new B('sven'); console.log(b.getName()); // 输出: 'sven' (function() { Array.prototype.push.call(arguments, 3); console.log(arguments); // 输出[1,2,3] })(1, 2); var a = {}; Array.prototype.push.call(a, 'first'); Array.prototype.push.call(a, 'two'); console.log(a.length); // 输出:2 console.log(a[0], a[1]); // first two //要求 1对象本身能够存取属性(number就不行) 2对象的lentgth属性可读写(函数不行) var func = function(){}; Array.prototype.push.call( func, 'first' ); console.log ( func.length );
3.闭包和高阶函数
var Type = {}; for ( var i = 0, type; type = [ 'String', 'Array', 'Number' ][ i++ ];){ (function( type ){ Type[ 'is' + type ] = function( obj ){ return Object.prototype.toString.call( obj ) === '[object '+ type +']'; } })( type ) }; Type.isArray( [] ); // 输出:true Type.isString( "str" ); // 输出:true
闭包用法
1.封装变量
var mult = (function() { var cache = {}; var calculate = function() { // 封闭 calculate 函数 var a = 1; for (var i = 0, l = arguments.length; i < l; i++) { a = a * arguments[i]; } return a; }; return function() { var args = Array.prototype.join.call(arguments, ','); if (args in cache) { return cache[args]; //保存的参数 若运算过 直接输出 否则运算 } return cache[args] = calculate.apply(null, arguments); } })();
2.高阶函数
// 1.callback 回调函数 // 2.Array.prototype.sort // 3. 判断数据的类型(返回值) var isType = function(type) { return function(obj) { return Object.prototype.toString.call(obj) === '[object ' + type + ']'; } }; 4. getSingle var getSingle = function(fn) { var ret; return function() { //单例模式简单实现 return ret || (ret = fn.apply(this, arguments)); }; }; // 高阶函数实现AOP // AOP(面向切面编程)的主要作用是把一些跟核心业务逻辑模块无关的功能抽离出来,这些 // 跟业务逻辑无关的功能通常包括日志统计、安全控制、异常处理等。把这些功能抽离出来之后, // 再通过“动态织入”的方式掺入业务逻辑模块中。这样做的好处首先是可以保持业务逻辑模块的 // 纯净和高内聚性,其次是可以很方便地复用日志统计等功能模块。 Function.prototype.before = function(beforefn) { var __self = this; // 保存原函数的引用 return function() { // 返回包含了原函数和新函数的"代理"函数 beforefn.apply(this, arguments); // 执行新函数,修正 this return __self.apply(this, arguments); // 执行原函数 } }; Function.prototype.after = function(afterfn) { var __self = this; return function() { var ret = __self.apply(this, arguments); afterfn.apply(this, arguments); return ret; } }; var func = function() { console.log(2); }; func = func.before(function() { console.log(1); }).after(function() { console.log(3); }); func(); //1 2 3 2.currying 柯里化 将一部分参数放入函数后返回另一个函数 直到需要时 一次性调用 var cost = (function(){ var args = []; return function(){ if ( arguments.length === 0 ){ var money = 0; for ( var i = 0, l = args.length; i < l; i++ ){ money += args[ i ]; } return money; }else{ [].push.apply( args, arguments ); } } })(); cost( 100 ); // 未真正求值 cost( 200 ); // 未真正求值 cost( 300 ); // 未真正求值 console.log( cost() ); // 求值并输出:600 //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 ); // 分批执行的时间间隔,也可以用参数的形式传入 }; }; //4.惰性加载函数 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); };
相关文章推荐
- 10大基础实用算法及解析
- Linux入门基础 #13:DNS基础及域名系统架构
- Objective-C基础语法快速入门
- 【SSH三大框架】Struts2基础第二篇:Struts2的Action访问ServletAPI
- Java基础复习---多态
- Mike学python(1):python的基础知识
- STM32基础知识1-stm32PWM输入捕获模式详解
- 很好的计算机基础知识比喻
- JavaWeb学习笔记-Web基础-01
- zookeeper 基础
- 使用Jquery解析Json基础知识
- halcon/c++接口基础 之内存管理
- Python基础——读写文件
- 20161214C语言基础10_运算符
- Android中OkHttp基础用法
- java基础-容器
- PHP基础——数组
- 绘图基础--检测在矩形中鼠标点击事件
- DIV+CSS教程《第一天 XHTML CSS基础知识》
- [049] 微信公众平台视频公开课1说话-基础知识