周五晚上下班回家的路上,突然想到了 CommonJS 规范、Node.js 模块化等等各种东西,然后就想到了熟悉的 module.exports
。
大约很久之前看 seajs
的文档,文档强调,exports = {/**/}
这种写法是错误的!当时还是小白中的小白,只能一脸懵逼,为嘛不能啊?完全无法理解。
请看截图:
有没有看到最后的提示?可惜那时候的小白文蔺完全不知道这是什么鬼——更可能的是那会儿就没关注到这一块儿,毕竟新人,心浮气躁,就想五分钟学会 seajs 模块化开发。
后来摸爬滚打,js 知识相对扎实之后(鸣谢厚厚的红宝书《 JavaScript 高级程序设计》,前后读了三遍),我还是好歹懂了,但未能举一反三。
昨天晚上,再次冒出这个问题,还是了然的。
子曰: 学而不思则罔,思而不学则殆。
很显然,exports
在 define(function(require, exports) {})
中就是个局部变量,它对应的值是个对象,是 module.exports
的一个引用。
然后呢,一句exports = {/**/}
就把这个局部变量指向另外一个值了。这是局部变量啊喂。卒。
很多新人看了一些博客或者书之后,脑子里也打结了,求值策略
,按值传递
,按引用传递
,这些似是而非的概念最后都把人给整糊涂了。
刚刚刷SF,读到一篇文章,《JS中的值是按值传递,还是按引用传递呢?》,和我思考的有点类似。
然后搜索了下 “求值策略”,找到汤姆大叔的一篇文章,上文与大叔的这篇文章还挺类似的,但大叔的可能显得更深入一点。
下面是引用:
准确的说,JS中的基本类型按值传递,对象类型按共享传递的(call by sharing,也叫按对象传递、按对象共享传递)。最早由Barbara Liskov. 在1974年的GLU语言中提出。该求值策略被用于Python、Java、Ruby、JS等多种语言。
该策略的重点是:调用函数传参时,函数接受对象实参引用的副本(既不是按值传递的对象副本,也不是按引用传递的隐式引用)。 它和按引用传递的不同在于:在共享传递中对函数形参的赋值,不会影响实参的值。
从科学的角度来说,对于概念什么的,可能还是挺有必要的。从实用角度来说,只要能正确理解,可能用自己的一套语言来描述也是可以的。