剖析 exports=module.exports=xxx 的写法

曾经好久好久被这两个东东搞的晕头转向,今天无意间看到了 cNode 社区一篇博客,给我了灵感,算是把这个问题彻底想通了。在作者原文的基础上加上图文解说,希望能把这个问题解释的更透彻点,对那些同样有疑惑的朋友们有些许启发。

1. js 中对象的复制是指针的复制

这句话最早在 《javascript 高级程序设计》中读到过,当时也明白具体咋回事,没想到挪到实际应用还是不能化为己用。

先看个例子:

var a = {'name': 1};
var b = a;
console.log(a);
console.log(b);

b.name = 2;
console.log(a);
console.log(b);

b = {'name': 3}
console.log(a);
console.log(b);

打印出来的结果是这样的:

{name: 1}       // a
{name: 1}       // b

{name: 2}       // a
{name: 2}       // b

{name: 2}       // a
{name: 3}       // b

下面来解释下为什么:

第一次操作 var b = a; 将 a 的值复制给 b,由于 a 是个对象,所以复制的是指向对象的指针,之后 b 才指向了同一个对象。

对象复制1

第二次操作通过 b 变量对对象进行了修改,由于 a 和 b 还是指向同一个对象,所以仍然斗都打印出 2。

对象复制2

第三次操作在变量值空间创建了一个新的对象,将赋值给 b,与将 a 的值复制给 b一样,此时 b 的指针指向了新的对象。

对象复制3

通过以上说明,可以得出结论:对象的复制是指针的复制。

2. 非对象的复制是值的复制

var a = 1;
var b = a;
console.log(a);
console.log(b);

b = 2;
console.log(a);
console.log(b);

打印结果为:

1       // a
1       // b

1       // a
2       // b

结论: 改变 b 的值并不会对 a 有任何影响,非对象值的复制就是值的复制。

3. 解释 exports=module.exxports=xxx的写法

node 中规定:

  • module.exports 初始值为一个空对象 {};

  • exports 是指向的 module.exports 的引用;

  • require() 返回的是 module.exports 而不是 exports。

依然用图文的方式解释:

  • 起初,module.exports 指向一个空对象,而 exports 指向 module.exports 的引用,也指向了这个空对象。

    exports 讲解1

  • 对 exports 对象添加 age 属性,并赋值 20,这里是为 exports 对象添加一个属性而不是对exports 对象进行赋值,所以引用依然没有改变

    exports 讲解2

  • 对 exports 对象添加 say 属性,值为一个方法。

    这里主要想说明白两个问题:

    • exports.say = function(){}

      为 exports 对象添加了一个属性,值为一个方法,不是一个复制操作,不会改变 exports 的引用

    • exports = function say () {}

      say 方法是个对象,将这个对象复制给左边的 exports 对象,此时会改变 exports 的引用

      exports 讲解3

  • 此时修改 module.exports 指向一个新的对象,改变了指针,导致 exports 不再指向 module.exports 的引用

    考虑到 require() 接收的是 module.exports 对象,而不是 exports 对象,这时候对 exports 做的任何操作都不会起作用了。

    exports 讲解4

  • 通过 exports = module.exports 将 exports 的指针再次指向 module.exports

    exports 讲解5

4. 结论

  • 非对象数据类型有字符穿(String)、数值(Number)、布尔值(Boolean)、Null、Undefined,这些类型对应的值的复制就是值的复制;

  • 对象(对象字面量 {}、数组[]、函数 Function等)的复制为引用(也叫指针)的复制;

results matching ""

    No results matching ""