Service vs Factory - Once and for all
原文链接
http://blog.thoughtram.io/angular/2015/07/07/service-vs-factory-once-and-for-all.html
只翻译了后半截,而且不好,留给自己看的,不喜勿喷。
factory()方法通过字符串名字和一个factoryFn传递参数,返回一个同名的provider对象,这个provider对象也就是factory函数,自带一个$get方法。provider的作用是,不管什么时候你向注册器请求一个特定的依赖,它基本上都会通过调用$get()方法向对应的provider请求service的一个实例。 这就是为什么在创建provider时需要$get()。
换句话说,如果我们在某个地方注入MyService,在屏幕后面进行了如下操作:
MyServiceProvider.$get(); // 返回服务的实例
factory函数只是被调用,那么service代码是如何工作的?
function service(name, constructor) {
return factory(name, ['$injector, function($injector) {
return $injector.instantiate(construtor);
}]);
}
这段代码证明了当我们调用service(),它实际是调用了factory()。但是这段代码并不是仅仅把service的构造函数传递给factory。
这段代码中传递了一个构造函数,该函数要求注册器为这个构造函数创建实例和对象。也就是说,一个service调用一个预定义的factory,当和provider通信时使用$get()方法结束。$injector.instantiate(constructor)实际上调用了Object.create()方法。这就是为啥在service()里边使用 this 关键字。
到底用哪个?
在网上问这个问题需要我们几篇文章和StackOverflow的答案。
首先是这个答案。 它说: service和factory的区别基本上就以下这么多:
app.service('myService', function() {
//service只是一个构造函数
//调用的时候new出来一个实例
this.sayHello = function(name) {
return "Hi " + name + " !";
};
});
app.factory('myFactory', function() {
//factory 返回一个对象
//你可以直接在这之前运行一些代码
return {
sayHello: function(name) {
return "Hi " + name + " !";
}
}
});
现在我们早就知道在屏幕背后发生了什么,但是这个答案又加了一个新评论。它说我们可以在返回对象字面量之前运行代码。当不能直接创建一个service时,这基本上允许我们做一些配置的东西或者视情况而定是否要创建对象,这就是为什么大多数资源推荐使用factory而不是service,但是这个原因并不是决定因素。
如果我告诉你,能用service完成上边的事呢?
是的,没错。一个service是一个构造函数,但是这并不是阻挡我们做一些额外的工作和返回一个对象字面量。实际上,在js中构造函数能够返回任何他们想返回的。所以我们可以用service把代码写出来,它的方式基本上和factory完全一样:
app.service('MyService', function() {
//我们也可以在这里做额外的工作
return {
sayHello: function() {
console.log('hello');
};
}
});
怎样,看到了吧,取决于如何写service代码,这两者之间根本没有区别。那么问题来了:到底应该用哪个?
Services 允许我们使用ES6 类
当然了,用这样的方式写service是完全反生产的,既然service被当做构造函数调用,那它就应该当做构造函数使用。那这样写有什么优点呢? 事实证明,在迁移到ES6时,尽可能使用服务更好。 原因就是service是构造函数,而factory不是。 在ES5中使用构造函数可以让我们在迁移到ES6时轻松使用ES6类。
例如,可以拿代码在ES6里边这样重写:
class MyService {
sayHello() {
console.log('hello');
}
}
app.service('MyService', MyService);
一个ES6类就是ES5中的一个构造函数,关于介绍在这里,如果你还没有阅读这篇文章,推荐你读一下。
对于factory来说,代码没什么可能性,因为他们只是被当做函数调用了。我希望这篇文章能让读者明白service和factory的关系,并且建议人们不要使用factory多于service,如果他们不知道怎么用的话。