本文只是一些很零散的东西,关于js的模板引擎方面的知识。
看 Node in Action的时候,有一章关于ejs,看到这样的一个片段:
<% if (locals.messages) { %>
后面省略若干行
这个 locals 让我迷惑不解,因为根据资料,express只是暴露了一个settings到app.locals,并没有暴露这个locals。
后来看了ejs的部分源码,才知道这个locals存在的原因,其实ejs工作机制的缘故。
现在开始说一下背景知识。
在js里,可以创建一个匿名函数,然后赋值给一个变量:
var fn = function(x, y) { return x + y; };
但是,除了这种方法,还有一种更灵活的方法来创建前面的函数:
var fn = new Function("x, y", "return x + y;");
这是很多魔法的来源,它实际上代表了一种思想:用代码创造代码
js里有一个with关键字, 先看个例子:
var t = { name : { firstname: "tom" }, age: 12 }
with (t.name) {
console.log(firstname); // 输出 tom
firstname = "jack"
}
console.log(t.name.firstname) // 输出 jack
没啥问题。但是,再看这个:
var t = { name : { firstname: "tom" }, age: 12 }
with (t.name) {
firstname = "jack"
console.log(firstname); // 输出 jack
console.log(t.name.firstname); //输出 jack
t.name = {
firstname: "mike"
};
console.log(firstname); // 输出 jack
console.log(t.name.firstname); //输出 mike
}
console.log(t.name.firstname) // 输出 mike
with里面发生了什么事情呢?其实很简单,可以这样理解上面的代码:
var t = { name : { firstname: "tom" }, age: 12 };
(function(scope) {
scope.firstname = "jack"
console.log(scope.firstname); // 输出 jack
console.log(t.name.firstname); // 输出 jack , 因为现在scope 和 t.name 是 同一个对象
t.name = {
firstname: "mike"
};
console.log(scope.firstname); // 输出 jack,因为 scope 和 现在的t.name 是两个独立无关的对象了!
console.log(t.name.firstname); //输出 mike
})(t.name); // 把 t.name 传进去
console.log(t.name.firstname) // 输出 mike
所谓指向对象的变量,其实就是指针而已。