问一个关于prototype的问题
发布于 9 年前 作者 im-here 3531 次浏览 最后一次编辑是 8 年前 来自 问答

第一种写法:A.js

function Test(){}
Test.prototype.do1=function(){
	//do1......
}
Test.prototype.do2=function(){
	//do2......
}
module.exports = Test;
//调用
var Test = require('./A.js');
var test = new Test();
test.do1();
test.do2();

另一种写法:B.js

exports.do1=function(){
	//do1......
}
exports.do2=function(){
	//do2......
}
//调用
var test = require('./B.js');
test.do1();
test.do2();

上面两种写法单从外表看好像就是调用的时候不同,其他都差不多。 我想问问这2者具体有什么区别,什么场合下用哪一种,或者是用法没区别,我一个项目全部都写成A或者全写成B,有影响吗? 刚接触js不就,还望各位多多指教!

8 回复

第一种写法是把函数当作类,用于创建对象,然后用对象调用其类的方法;第二种直接把函数导出了;如果你Test函数中有私有变量,比如

function Test(a){
	this.a =a
}
//第一种方法可以在 do1函数中通过 this.a访问那个变量

第二种是CommonJS的写法,如果在浏览器的话,不直接支持

@Alexis374 那就是说 如果不考虑私有变量和浏览器支持的话,这两种写法在整个项目中我全用其中一种是没任何问题的了?

理解不准确,第一种是导出一个类,你new出来就是新的实例了,多用于对某个业务的抽象,需要有互不干扰的实例的场合。 第二个是导出对象(细微差别自己摸索),这个对象有两个方法可用, 而第二种,是全局共享的实例,多用于数据库连接,remoteCall链接等只需要一个实例的底层功能的场合。

这个问题问的…

我个人觉得, 如果你发现你要实现的功能用 B 写法可以顺利写出来. 那就不要用 A 写法了. 如果用 B 方法写着写着发现不对, 有些变量的传递特别别扭. 有的时候这个 test 对象的状态还需要改变什么的, 那就说明需要用 A 写法.

我觉得楼主症结在于没有理解面向对象是怎么回事, 或者说是没明白什么情况下需要使用 OO 思想去设计一个模块, 什么时候只是需要一个 util 模块将自己需要的独立功能函数一股脑装进去.

@Chunlin-Li 拿用户登录来说吧,假如我有个login类,专门用来管理用户登录的。 A写法:每个用户上来的时候我都会new一个login来处理该用户的登录逻辑,那么每个用户都是独立的,互不影响。 B写法:所有用户都共用login这一个类。 我不知道这两种做法效率上会不会有什么不同。A写法好理解,各个用户是独立的。但是B写法,假如有一个用户正在进行登录过程,登录相关的代码逻辑还没走完,这时候又来了一个用户,这时候代码执行顺序是怎样的?是后面这个用户会等待让前一个用户把代码执行完在走呢还是怎么的呢?

@imhered

不能完全了解到业务的所有细节, 我就按我的感觉说了.

用户登录这种业务, 应该用 B 写法好一些, 或者说是我倾向 B 写法. 每个用户登录, 你可能需要维护当前用户的状态, 这需要你有其他的某个类来做这个工作, 比如 UserState 什么的, 但反正不是 login. login 就做成一个函数, 输入是一个用户状态对象, 输出是执行后的用户状态对象(可是是登录成功, 也可能是登录失败, 那是下一个模块要处理的问题了).

你说的一个用户正在登录问题, 如果此时代码正在 Login 中执行, 那么另一个用户就登录不进来, 因为 js 单线程. 如果此时用户1的 Login 过程执行到了异步的部分, 比如验证 token 什么的, 那么此时 用户2的请求进来, 调用 login 函数也不会有问题. 他们的 scope 是隔离的. 极端情况下, 有 1000 用户同一秒内登录, 你的进程处理不过来, 那么结果也就是后面发请求的用户觉得怎么今天登录比前几天要慢一点啊…

@Chunlin-Li 非常感谢!

回到顶部