js设计模式基础
来源:互联网 发布:pl sql developer官网 编辑:程序博客网 时间:2024/04/29 12:18
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); // ducksayName(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: function(){ 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); // 输出:2console.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( [] ); // 输出:trueType.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. getSinglevar 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 32.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);};
阅读全文
0 0
- js设计模式基础
- js基础对象-编程模式与设计模式
- js设计模式 基础篇(单体,工厂,桥接)
- JS设计模式
- js设计模式
- js 设计模式 参考
- js设计模式
- JS设计模式
- js设计模式
- JS设计模式 零
- JS设计模式 零
- JS设计模式 零
- JS设计模式0
- JS设计模式
- JS设计模式
- js设计模式
- js设计模式
- JS设计模式
- ANDROID样式的开发:PROPERTY ANIMATION篇
- Linux入门,这七大习惯得有!
- 进出队列
- Ubuntu下pip的安装及配置
- OpenCV3图像形态学处理
- js设计模式基础
- Git常用命令清单总结
- 第五天-python数据类型-1
- 自定义View倒计时
- 【Java学习笔记】44:JFrame布局管理
- Leetcode-BFS广度优先搜索
- Java编程思想读书笔记——通过异常处理错误(二)
- qemu内存泄漏
- mysql存储过程