在学习关于JavaScript的装饰者设计模式的过程中,发现其实现方式的关键在于this的使用。

  想象一个匿名函数(其实预定义的有名函数也可以,都存在引用),其中的this:

 // 我们先定义一个匿名函数的引用foo
var foo = function(){
console.log(`我是 ${this}`)}; //创建一个空的Object实例 var bar = {}; //很空 但是依然有其默认原型Object.prototype的方法和属性 //如果我们写出下列语句 bar.foo = foo; //这意味着把上面定义的匿名函 ”挂载“到实例bar的foo方法中 //
bar.foo() //我是 [object Object](bar)。这里其实调用了Object原型上的toString方法,下同。 foo() // 我是 [object global](node: global/ 浏览器: window)

  到这里,读者可能会疑惑,这个”挂载“的过程跟题目的AOP装饰函数有什么关系。

  在JS中,装饰模式的实现简单来说就是 将对象的某个原方法与其他的函数进行加工合并,从而输出一个”匿名函数“, 就像上面代码定义的匿名函数一样,将这个输出的”匿名函数“,”挂载到原对象的原方法上面“,就完成了在原方法前后产生附加动作的效果。

  我们给出AOP的基础实现代码,一步步的分析:

 //首先定义对象
//这个对象有属性score,以及方法main var bar = {
score : 60,
main: function(){ console.log("我的分数"+this.score);}
}; //突然,我想另外输出bar同学分数的平方根, 要求不过分吧
//可能你会想到,在bar同学中添加新的方法去输出平方根,或者定义一个新的函数去处理bar同学的分数。 //接下来,我们利用AOP来实现这个方法 Function.prototype.after= function(fn){
var _self = this;
return function(){
var result = _self.apply(this,arguments);
fn.apply(this,arguments);
return result; };
}; //输出平方根的函数
function sqrt(){
console.log("我的分数的平方根"+Math.sqrt(this.score));}
//挂载到main上 bar.main = bar.main.after(sqrt); //输出新的合成匿名函数
bar.main();//我的分数60
// 我的分数的平方根7.745966692414834

  看到14-20行的代码中的this,其实我一开始有点懵,第一个this指的是 Function实例——即bar.main,而返回的匿名函数中的this是指其挂载的对象,这里是挂载的是bar,如果不挂载的话,这个this就指向运行环境的顶层对象或者null,这是需要关注的地方,换句话说,如果没有那两句apply语句,那么合成匿名函数的这些函数集合中的this可能会丢失,而指向顶层对象或者null。

  所以在装饰者模式中,this的指向与是否挂载息息相关,进一步的说,在代码的某个地方使用this,无论是函数声明的语句,还是运行上下文中的语句,及时保存this的指向和挂载正确的对象 都是十分必要的!

关于AOP装饰函数中的this的更多相关文章

  1. Python-装饰器中保留被装饰函数元数据

     函数的元数据包括哪些呢? 1. 函数名 .__name__ 2. 函数注释 .__doc__ ... 那,如何保留被装饰函数元数据,通过wraps装饰器保留被装饰函数的元数据 import time ...

  2. Spring AOP在函数接口调用性能分析及其日志处理方面的应用

    面向切面编程可以实现在不修改原来代码的情况下,增加我们所需的业务处理逻辑,比如:添加日志.本文AOP实例是基于Aspect Around注解实现的,我们需要在调用API函数的时候,统计函数调用的具体信 ...

  3. Python 装饰器装饰类中的方法

    title: Python 装饰器装饰类中的方法 comments: true date: 2017-04-17 20:44:31 tags: ['Python', 'Decorate'] categ ...

  4. python_如何修改装饰器中参数?

    案例: 为分析程序内哪些函数执行时间开销较大,我们需定义一个带timeout参数的装饰器 需求: 统计被装饰函数的运行时间 时间大于timeout时,将此次函数调用记录到log日志中 运行时可以修改t ...

  5. Python装饰函数

    from time import ctime, sleep def tsfunc(func): def wrappedFunc(): print('[%s] %s() classed' % (ctim ...

  6. python函数中闭包的概念说明

    函数中闭包的概念说明 闭包: 内层函数对外层函数非全局变量的引用,就叫做闭包 判断闭包方法 ._closure_ : 执行后返回有效信息就是闭包,返回none就不是闭包 举例1: 是闭包 def wr ...

  7. python函数中的参数(关键字参数,默认参数,位置参数,不定长参数)

    默认参数:定义函数的时候给定变量一个默认值. def num(age=1): 位置参数:调用函数的时候根据定义函数时的形参位置和实参位置进行引用. 关键字参数:如果定义的函数中含有关键字参数,调用函数 ...

  8. python 装饰函数2

    #!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Created on Tue May 5 21:40:49 2020 ...

  9. JS中bind、call和apply的作用以及在TS装饰器中的用法

    目录 1,前言 1,call 1.1,例子 1.2,直接调用 1.3,将this指向另一个对象 1.4,传递参数 2,apply 2.1,例子 2.2,直接调用 2.3,将this指向另一个对象 2. ...

随机推荐

  1. 【Alpha】第四次Daily Scrum Meeting

    GIT 一.今日站立式会议照片 二.会议内容 1.采取老师提出的建议,考虑对送礼对象进行一个分类,这个在服务功能模块中完善. 2.回顾之前几次会议的内容,做一个小的总结,各抒己见,对每个人哪方面做得比 ...

  2. Coding使用方法

    首先在码市coding.net上创建账号 基础配置 1. 首先,下载安装git客户端和tortoisegit(就是小乌龟,本地右键使用的,跟SVN一样的那个小乌龟). git下载官网:https:// ...

  3. 201521123018 《Java程序设计》第6周学习总结

    1. 本章学习总结 2. 书面作业 一.clone方法 1.1 Object对象中的clone方法是被protected修饰,在自定义的类中覆盖clone方法时需要注意什么? 用protected修饰 ...

  4. 201521123007《Java程序设计》第9周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常相关内容. 2. 书面作业 本次PTA作业题集异常 1. 常用异常 题目5-1 1.1 截图你的提交结果(出现学号) 1.2 自 ...

  5. 201521123066 《Java程序设计》第十周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常与多线程相关内容. 有关异常的知识点: 一段代码可能生成多种类型的异常,子类异常必须放在父类异常前面,否则会出现编译错误: 可以 ...

  6. 复用代码【SSH配置文件】

    web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="htt ...

  7. session get和load方法对比

    get测试代码如下: public class Test { public static void main(String[] args) { // TODO Auto-generated metho ...

  8. CSS3的颜色渐变效果

    在 animate.css寻找自己想要的动态效果,看到标题Animate.css和按钮Animate it的颜色在逐渐变化,觉得蛮有趣的,把控制变化的相关代码扒了下来,自己分析实现一波. 一开始认为使 ...

  9. hadoop大事件

    大事件:  Hadoop新一代(2.x)计算平台YARN 一代hadoop存在的问题: 1.Jobtracker单点,容易导致崩溃,节点较多时造成性能瓶颈 2.作业分配基于槽位(slot),分配粒度 ...

  10. 第1回-使用ThinkPHP的3.1.3版本轻松建网站

    使用ThinkPHP的3.1.3版本轻松建网站 首先,从ThinkPHP官网下载一个ThinkPHP3.1.3版本框架包. 其次,取出ThinkPHP3.1.3包中的核心部分,部署你的服务器项目下. ...