Node.js中看JavaScript的引用

2020-06-17 07:02:02易采站长站整理
var b = include(‘./b')
,在文件 b.js 更新之后 include 内部可以自动刷新,让外面拿到最新的代码。

但是实际的开发过程中,这样很快就碰到了问题。我们希望的代码可能是这样:

web.js


var include = require('./include');
var express = require('express');
var b = include('./b.js');
var app = express();
app.get('/', function (req, res) {
res.send(b.num);
});
app.listen(3000);

但按照这个目标封装include的时候,我们发现了问题。无论我们在include.js内部中如何实现,都不能像开始那样拿到新的 b.num。

对比开始的代码,我们发现问题出在少了 b = xx。也就是说这样写才可以:

web.js


var include = require('./include');
var express = require('express');
var app = express();
app.get('/', function (req, res) {
var b = include('./b.js');
res.send(b.num);
});
app.listen(3000);

修改成这样,就可以保证每次能可以正确的刷新到最新的代码,并且不用重启实例了。读者有兴趣的可以研究这个include是怎么实现的,本文就不深入讨论了,因为这个技巧使用度不高,写起起来不是很优雅[1],反而这其中有一个更重要的问题——JavaScript的引用。

JavaScript 的引用与传统引用的区别

要讨论这个问题,我们首先要了解 JavaScript 的引用于其他语言中的一个区别,在 C++ 中引用可以直接修改外部的值:


#include
using namespace std;
void test(int &p) // 引用传递 {
p = 2048;
}
int main() {
int a = 1024;
int &p = a; // 设置引用p指向a
test(p); // 调用函数
cout << "p: " << p << endl; // 2048
cout << "a: " << a << endl; // 2048
return 0;
}

而在 JavaScript 中:


var obj = { name: 'Alan' };
function test1(obj) {
obj = { hello: 'world' }; // 试图修改外部obj
}
test1(obj);
console.log(obj); // { name: 'Alan' } // 并没有修改①
function test2(obj) {
obj.name = 'world'; // 根据该对象修改其上的属性
}
test2(obj);
console.log(obj); // { name: 'world' } // 修改成功②

我们发现与 C++ 不同,根据上面代码 ① 可知 JavaScript 中并没有传递一个引用,而是拷贝了一个新的变量,即值传递。根据 ② 可知拷贝的这个变量是一个可以访问到对象属性的“引用”(与传统的 C++ 的引用不同,下文中提到的 JavaScript 的引用都是这种特别的引用)。这里需要总结一个绕口的结论:Javascript 中均是值传递,对象在传递的过程中是拷贝了一份新的引用。