JS方法代理
作者:Jiang, Jilin
JS作为一门脚本语言。十分easy上手。外加其灵活性,能够轻而易举地扩展功能。今天,我们就聊聊JS的方法代理。
方法代理是脚本语言中常见的方法扩展形式。这样的灵活的形式长处在于遇到复杂的JS代码须要扩展时,能够相对简单的抽取并改动。可是,其缺点也十分明显,会造成代码的碎片化,因而是一把双刃剑。
基本形式
|
var _func = obj.func; obj.func = function() { return _func(); }; |
此处。obj的func方法是原始方法。
我们使用一个_func变量保存该方法。之后重写func方法。返回调用原始的方法。
相当的好理解。
不定长參数
有时候,我们会遇到不定长參数的形式。那么我们能够做下面更改:
|
var _func = obj.func; obj.func = function() { return _func.apply(this, arguments); }; |
写到这里,JS方法代理的两种形式已经写完了。这时。你可能会疑惑这样的方法代理有什么用?那么,就尾随我看看几个样例吧:
重写静态方法
出于某些原因。我们须要在console打印的同一时候,将打印传输数据到指定server上用户帮助统计数据。而在开发过程中,直接使用了原生态的console.log方法输出。那么。我们就可做例如以下改动。
首先,构建代理方法:
|
var _log = console.log; console.log = function() { return _log.apply(this, arguments); }; |
接着,插入ajax调用逻辑:
|
console.log = function() { var _args = Array.prototype.slice.call(arguments); $.post("srvAddr", {userID: userID, args: _args}); return _log.apply(this, arguments); }; |
能够非常easy预见效果:
原型代理
有时候,我们须要直接接管一个类的方法。
那么对应的。我们就要将其prototype中的方法做代理。如今我们如果要使得Array默认支持数字排序:
|
var _sort = Array.prototype.sort; Array.prototype.sort = function() { _sort.apply(this, arguments); }; |
我们首先检測数组中的元素是否是数字。假设是则依照数字排序,否则就依照默认方式排序:
|
var _sort = Array.prototype.sort; Array.prototype.sort = function() { var _isNum = true; for(var i = 0 ; i < this.length ; i += 1) { if(typeof this[i] !== "number") { _isNum = false; break; } } if(_isNum) { return _sort.call(this, function(a, b) { return a - b; }); } else { return _sort.apply(this, arguments); } }; |
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZWJheQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
原始排序方式(将数字转换成字符排序)
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZWJheQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
代理后排序方式
注意:此处仅作为原型方法代理的样例。
在实际开发中。应该尽量避免对原生对象原型方法做代理。
重载
在jQuery中,toggle方法拥有多种重载。当中一个为toggle(display)。通过接受boolean參数来决定元素显示还是隐藏。
而fadeToggle方法则不接受该參数。
让我们进行简单的代理,使其支持boolean參数:
|
var _fadeToggle = $.fn.fadeToggle; $.fn.fadeToggle = function(display) { if(arguments.length === 1 && typeof display === "boolean") { if(display) { return this.fadeIn(); } else { return this.fadeOut(); } } return _fadeToggle.apply(this, arguments); }; |
通过參数长度和接收參数类型类型推断是否调用fadeIn或fadeOut方法。假设不匹配则调用原来的fadeToggle方法。以此类推,slideToggle也能够相同适用。
*继承
继承中,我们有时候会须要调用父类方法来实现。这和java中的super有些类似。一个简单的样例。我们定义了一个Person,能够laugh。
同一时候定义一个Robot继承,是其沿用Person的laugh可是稍作改动:
|
var Person = function() { this.name = ""; this.laugh = function() { return "Ha ha!"; }; return this; }; var Robot = function() { Person.apply(this); var _laugh = this.laugh; this.laugh = function() { return encodeURIComponent(_laugh()); }; return this; }; |
劫持
说到劫持,则和安全性開始挂钩了。
现在大多数站点都习惯于使用开源的js库来开发,可是假设碰巧被插入了恶意代码,那么安全也就变得不安全了(比如chrome中大量未经验证的游览器插件)。
下面,我们将举几个劫持的样例。
Ajax劫持
不少人以为,通过闭包的方式将重要用户參数存储在作用域内(比如动态生成的secureID)。那么即便是被插入了恶意代码也无法获取到。从而无法伪造ajax请求来获取重要信息似乎就足够了。可是假设整个ajax请求被拦截了呢?
|
var _ajax = $.ajax; $.ajax = function() { var $p = _ajax.apply($, arguments); $p.done(function(data) { // Do something... }); return $p; }; |
jQuery中全部ajax请求(get,post,getJSON)终于都会调用$.ajax来实现。而通过方法代理直接劫持$.ajax方法并返回一个正常promise对象,会使得页面脚本执行毫无影响。可是实际上数据已经被劫持走了。
Array劫持
Array拥有不少原型方法。比如push,pop,shift,unshift等等。我们仅仅须要简单的代理数组操作方法,便能够截获数据。
|
var _push = Array.prototype.push; Array.prototype.push = function() { // Do something... return _push.apply(this, arguments); }; |
好了,以上就是这次的方法代理介绍。因为方法代理会混乱代码逻辑使得代码结构变得不易理解。
在日常开发过程中,我们应该尽量避免使用它。仅仅有在代理重载,或者更改难以理解的遗留代码的部分逻辑时使用它。
从而避免将双刃剑误伤了自己。
JS方法代理的更多相关文章
- JS调用OC方法并传值,OC调用JS方法并传值////////////////////////zz
iOS开发-基于原生JS与OC方法互相调用并传值(附HTML代码) 最近项目里面有有个商品活动界面,要与web端传值,将用户在网页点击的商品id 传给客户端,也就是js交互,其实再说明白一点 ...
- C# 解析js方法,并调用js方法
本文转载:http://www.cnblogs.com/StudyLife/archive/2013/03/11/2953516.html 本文不是基于B/S的 后台调用前台js方法,而是给你一段js ...
- 服务器文档下载zip格式 SQL Server SQL分页查询 C#过滤html标签 EF 延时加载与死锁 在JS方法中返回多个值的三种方法(转载) IEnumerable,ICollection,IList接口问题 不吹不擂,你想要的Python面试都在这里了【315+道题】 基于mvc三层架构和ajax技术实现最简单的文件上传 事件管理
服务器文档下载zip格式 刚好这次项目中遇到了这个东西,就来弄一下,挺简单的,但是前台调用的时候弄错了,浪费了大半天的时间,本人也是菜鸟一枚.开始吧.(MVC的) @using Rattan.Co ...
- 【问题】Asp.net MVC 的cshtml页面中调用JS方法传递字符串变量参数
[问题]Asp.net MVC 的cshtml页面中调用JS方法传递字符串变量参数. [解决]直接对变量加引号,如: <button onclick="deleteProduct('@ ...
- 解决webkit浏览器中js方法中使用window.event提示未定义的问题
这实际上是一个浏览器兼容性问题,根源百度中一大堆,简要说就是ie中event对象是全局变量,所以哪里都能使用到,但是webkit内核的浏览器中却不存在这个全局变量event,而是以一个隐式的局部变量的 ...
- ASP.Net 在Update Panel局部刷新后 重新绑定JS方法
我们知道Asp.Net中的Update Panel可以完成页面的局部刷新(实质上是Ajax),但是局部刷新完后,此区域的控件上所绑定的JS方法就会失效,因为我们用如下方法来重新绑定. var prm ...
- 常用js方法
function dateGetter(name, size, offset, trim) { offset = offset || 0; return function (date) { var v ...
- 与考试相关的JS方法
var IsChange = 0;var ensure = 0;var timeCounter = (function () {//考试剩余时间 倒计时 var int; //var total = ...
- Java使用正则表达式取网页中的一段内容(以取Js方法为例)
关于正则表达式: 表1.常用的元字符 代码 说明 . 匹配除换行符以外的任意字符 \w 匹配字母或数字或下划线或汉字 \s 匹配任意的空白符 \d 匹配数字 \b 匹配单词的开始或结束 ^ 匹配字符串 ...
随机推荐
- Delphi 自动检测U盘插入、拔出及获取U盘盘符!
http://qqhack8.blog.163.com/blog/static/1141479852012102133475/ Delphi 自动检测U盘插入.拔出及获取U盘盘符! u盘的 插 ...
- CAD中如何裁剪需要的区域
M1: 先转换为块的方式进行裁剪 大范围框选复制出来>>B命令生成块>>XC命令>>选择刚才生成的块>>空格>>新边界>>框选新 ...
- SQLSERVER中汉字提取首字母的拼音函数的实现
--创建一个汉字提取首字母的函数--还存在一点小小的问题(符号?)create function hs(@a varchar(1000)='')returns varchar(1000)asbegin ...
- Kubernetes环境下调整WebLogic JVM基本参数
基于Kubernetes启动WebLogic后,发现JVM的最大heap size一直在700多M左右,通过 kubectl logs 察看pod启动状态,发现日志中并没有-Xms和-Xmx参数.日志 ...
- 基于CentOS与VmwareStation10搭建Oracle11G RAC 64集群环境:3.安装Oracle RAC-3.6.集群管理命令
3.6. 集群管理命令 3.6.1. RAC的启动与关闭 oracle rac默认会开机自启动,如需维护时可使用以下命令: 关闭: crsctl stop cluster 停止本节点集群服务 crsc ...
- Highcharts、AJAX、JSON、JQuery实现动态数据交互显示图表柱形图
上个图给大家看下效果. 点击 查看图表 如下图展示效果 Highcharts简介 Highcharts 是一个用纯JavaScript编写的一个图表库, 能够很简单便捷的在web网站或是web应用程 ...
- 从HTML5移动应用现状谈发展趋势
时光如梭,自2008年HTML5诞生以来已经过去了5年的时间,作为新一代的Web标准,它自问世以来就受到方方面面的强烈关注,也引起了许多争议,支持者因其开放强大的特点而鼓吹它的美好前景,质疑者因其迟迟 ...
- 自己亲自写的两本linux资料,免费下载,pdf文档
第一本是我写的韩顺平老师解说的linux视频的笔记,该视频原本有21讲.可是我始终没有找到当中的17.18讲.可是其它部分我感觉及记录的还是蛮认真的.该套视频解说的非常基础,因此我的这本笔记也非常基础 ...
- Apache 配置:是否显示文件列表
Apache 配置:是否显示文件列表 进入虚拟主机配置文件 显示文件列表的话 options Indexes FollowSymLinks 不显示文件列表的话 options FollowSymLin ...
- Vue 状态管理 Vuex
1.概述 Vuex作为插件,管理和维护整个项目的组件状态. 2.安装vuex cnpm i --save vuex 3.vuex使用 github地址:https://github.com/MengF ...