问题描述
@EnableAspectJAutoproxy
@Aspect
@Component
public class Logger {
@pointcut("execution(* asss.pj.projekat_bioskop.controller.*.*(..))")
public void allRESTMethods(){};
@Around("allRESTMethods()")
public void blabla(ProceedingJoinPoint pjp) {
//@Before
String methodName = pjp.getSignature().getName();
String before = "*** Attempting " + methodName + " method ***";
writeLog(before);
try {
//@AfterReturning
pjp.proceed();
String success = "\n*** Method " + methodName + " has succeeded";
writeLog(success);
} catch (Throwable throwable){
//@AfterThrowing
String Failed = "\n*** Method " + methodName
+ " has Failed. " + throwable.getMessage() + " .***";
writeLog(Failed);
}
//@After
String after = "\n";
writeLog(after);
}
public void writeLog(String log){
File file = new File("filmovi_izvestaj.txt");
try (Writer wr = new FileWriter(file,true)){
wr.write(log);
} catch(FileNotFoundException fe){
fe.printstacktrace();
} catch(IOException ioe){
ioe.printstacktrace();
}
}
当我把这段代码放到 AST 资源管理器中并运行它时。我实际上看到在执行代码之前,名称已经分配给变量“Lydia”。我知道 AST 是在代码运行之前创建的。但是当代码被执行时,它返回 undefined。我对此很困惑,请您帮帮我
解决方法
该代码段中有两个同名的变量 (name
)。如果您仔细查看生成的 AST,您会看到两个声明。
AST 没有显示两个声明的范围,这是一个重要方面。变量的作用域是程序中变量名称可见的区域;也就是说,与变量相关联。两个变量同名是完全合法的;如果它们有重叠的作用域,则内部作用域将覆盖外部作用域。
所有这些对于大多数编程语言来说都是通用的,但是 ECMAScript 的范围规则比一般规则要复杂得多(这在一定程度上就是为什么 AST 工具显示范围会很有用)。 ECMAScript 具有两组不同的范围规则,一组用于使用 var
声明的变量,另一组用于使用 let
或 const
声明的变量。
虽然这个简单的例子没有显示所有的差异,但它确实显示了一个重要的差异:虽然内部 var
声明的 name
可以在初始化之前使用,导致值undefined
,在初始化之前不能使用let
声明的age
,导致抛出错误。 (let
声明的变量在初始化之前处于所谓的“临时死区”中。)
本示例中未显示的区别在于函数 sayHi
内声明的变量范围的边界。 var
声明的变量的范围是声明它的最里面的函数体(包括在同一范围内声明的任何函数,除非它们具有相同名称的覆盖声明)。另一方面,let
声明的变量的范围仅限于最内部的封闭块。但在本例中,内部 var name
和 let age
的最内部封闭块是函数 sayHi
的主体。
在 ECMAScript 中,变量的作用域始终是整个块。这与 C 等语言形成对比,在 C 语言中,变量的范围仅从变量的声明扩展到封闭块的结尾。这在这种情况下会有所不同:在 C 范围规则下,name
中的 console.log(name)
将引用外部声明,因为内部声明在代码中更靠后,因此其作用域尚未开始然而。而 age
中的 console.log(age)
是非法的,因为没有声明 age
的封闭作用域。但是在 ECMAScript 中,声明被“提升”以包含整个块,从而创造了临时死区的可能性。
虽然这可能已经是太多信息了,但我应该注意,我并没有真正涵盖 ECMAScript 或 C 中范围界定的所有奇怪问题,而且其他语言有其他细微不同的范围界定规则。