函数装饰器(AOP面向切面编程)的主要作用是把一些跟核心业务逻辑模块无关的功能抽离出来,这些跟业务逻辑无关的功能通常包括日志统计,安全控制,异常处理等。把这些功能抽离出来后,再通过动态织入的方式掺入业务逻辑模块中
实现一个简单的AOP
js
Function.prototype.before = function(beforeFn) {
var _self = this;
return function() {
beforeFn.apply(this,arguments);
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
不污染原型的实现
js
function before(fn, beforeFn) {
return function() {
beforeFn.apply(this, arguments)
return fn.apply(this, arguments)
}
}
function after(fn, afterFn) {
return function() {
var ret = fn.apply(this, arguments)
afterFn(this, arguments)
return ret
}
}
应用实例一:数据埋点上报。
分离业务代码和数据统计代码,无论在什么语言中,都是AOP的经典应用之一。
html
<button id="btnLogin">点击打开登录浮层</button>
js
// 数据上报
Function.prototype.before = function (beforeFn) {
var _self = this;
return function () {
beforeFn.apply(this, arguments);
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 showLogin = function() {
console.log('打开登录浮层');
}
// 依次输出:按钮点击之前上报 打开登录浮层 按钮点击之后上报
document.getElementById('btnLogin').onclick = showLogin.before(function(){
console.log('按钮点击之前上报');
}).after(function() {
console.log('按钮点击之后上报');
});
应用实例一:表单验证
html
用户名:<input type="text" id="username">
密码:<input type="password" id="password">
<button id="loginBtn">登录</button>
js
Function.prototype.before = function (beforeFn) {
var _self = this;
return function () {
if(beforeFn.apply(this,arguments)===false) {
// 未验证通过,不再执行原函数
return ;
}
return _self.apply(this, arguments);
}
}
var username = document.getElementById('username');
var password = document.getElementById('password');
var loginBtn = document.getElementById('loginBtn');
// 验证函数
var validate = function() {
if(username.value === '') {
console.log('用户名不能为空');
return false;
}
if(password.value === '') {
console.log('密码不能为空');
return false;
}
}
// 登录ajax
var formSubmit = function() {
var params = {
username: username,
password: password
}
console.log('登录ajax...');
}
// 登录按钮点击
formSubmit = formSubmit.before(validate);
loginBtn.onclick = function() {
formSubmit();
};
点个赞~~, 一起学习,一起进步