Confused about Service vs Factory
据我所知,在工厂里,我返回一个被注入控制器的对象。在服务内部,我使用
我假设服务始终是单例的,并且每个控制器中都注入了一个新的工厂对象。然而,事实证明,工厂对象也是单例的?
要演示的示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | var factories = angular.module('app.factories', []); var app = angular.module('app', ['ngResource', 'app.factories']); factories.factory('User', function () { return { first: 'John', last: 'Doe' }; }); app.controller('ACtrl', function($scope, User) { $scope.user = User; }); app.controller('BCtrl', function($scope, User) { $scope.user = User; }); |
在更换
我的假设是在控制器中注入了一个工厂的新实例?
所有角度服务均为单件:
docs(见服务单件):https://docs.angularjs.org/guide/services
Lastly, it is important to realize that all Angular services are application singletons. This means that there is only one instance of a given service per injector.
基本上,服务和工厂的区别如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | app.service('myService', function() { // service is just a constructor function // that will be called with 'new' this.sayHello = function(name) { return"Hi" + name +"!"; }; }); app.factory('myFactory', function() { // factory returns an object // you can run some code before return { sayHello : function(name) { return"Hi" + name +"!"; } } }); |
查看有关$provide的演示文稿:http://slides.wesalvaro.com/20121113/#/
这些幻灯片用于AngularJS会议:http://blog.angularJS.org/2012/11/more-angularJS-meetup-videos.html
对我来说,当我意识到它们都以相同的方式工作时,启示就出现了:运行一次某个东西,存储它们得到的值,然后在通过依赖注入引用时,将相同的存储值吐出来。
说我们有:
1 2 3 | app.factory('a', fn); app.service('b', fn); app.provider('c', fn); |
这三者的区别在于:
也就是说,在Angular中有类似缓存对象的东西,每次注入的值只分配一次,当它们第一次被注入时,在哪里:
1 2 3 | cache.a = fn() cache.b = new fn() cache.c = (new fn()).$get() |
这就是为什么我们在服务中使用
希望这有帮助。
活生生的例子"Hello World"示例
使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | var myApp = angular.module('myApp', []); //service style, probably the simplest one myApp.service('helloWorldFromService', function() { this.sayHello = function() { return"Hello, World!" }; }); //factory style, more involved but more sophisticated myApp.factory('helloWorldFromFactory', function() { return { sayHello: function() { return"Hello, World!" } }; }); //provider style, full blown, configurable version myApp.provider('helloWorld', function() { // In the provider function, you cannot inject any // service or factory. This can only be done at the //"$get" method. this.name = 'Default'; this.$get = function() { var name = this.name; return { sayHello: function() { return"Hello," + name +"!" } } }; this.setName = function(name) { this.name = name; }; }); //hey, we can configure a provider! myApp.config(function(helloWorldProvider){ helloWorldProvider.setName('World'); }); function MyCtrl($scope, helloWorld, helloWorldFromFactory, helloWorldFromService) { $scope.hellos = [ helloWorld.sayHello(), helloWorldFromFactory.sayHello(), helloWorldFromService.sayHello()]; }? |
还有一种返回构造函数函数的方法,这样您就可以在工厂中返回新的类,如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 | function MyObjectWithParam($rootScope, name) { this.$rootScope = $rootScope; this.name = name; } MyObjectWithParam.prototype.getText = function () { return this.name; }; App.factory('MyObjectWithParam', function ($injector) { return function(name) { return $injector.instantiate(MyObjectWithParam,{ name: name }); }; }); |
因此,可以在使用myObjectWithParam的控制器中执行此操作:
1 | var obj = new MyObjectWithParam("hello"), |
请参阅以下完整示例:http://plnkr.co/edit/gkhin?P=预览
这里是谷歌集团的网页,在这里讨论:https://groups.google.com/forum/!消息/角度/56S或WEOQG/B8HDPSKXZXSJ
主要区别如下:
服务语法:
结果:当将servicename声明为可注入参数时,将向您提供传递给
用法:对于共享实用程序函数很有用,这些函数可以通过简单地将()附加到注入的函数引用来调用。也可以与
语法:
结果:将factoryname声明为可注入参数时,将通过调用传递给
用法:对于返回"class"函数很有用,该函数随后可以被新建以创建实例。
还可以查看AngularJS文档和StackOverflow上的类似问题,这些问题混淆了服务与工厂之间的关系。
下面是使用服务和工厂的示例。了解更多关于AngularJS服务与工厂的信息。
添加到第一个答案,我想.Service()是为那些以更面向对象的方式编写代码的人(Cy/Java/Java)(使用这个关键字并通过原型/构造函数实例化对象)。
工厂是为那些编写代码的开发人员而设计的,这对于JavaScript/函数式的编码更为自然。
查看angular.js中的.service和.factory方法的源代码-在内部,它们都调用provider方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | function provider(name, provider_) { if (isFunction(provider_)) { provider_ = providerInjector.instantiate(provider_); } if (!provider_.$get) { throw Error('Provider ' + name + ' must define $get factory method.'); } return providerCache[name + providerSuffix] = provider_; } function factory(name, factoryFn) { \ return provider(name, { $get: factoryFn }); } function service(name, constructor) { return factory(name, ['$injector', function($injector) { return $injector.instantiate(constructor); }]); } |
非常简单:
.service-已注册函数将作为构造函数调用(也称为"newed")。
.factory注册函数将作为简单函数调用
两者都会被调用一次,导致一个单例对象被注入到应用程序的其他组件中。
所有提供程序的工作方式都相同。不同的方法
另外还有
从
这是一张图片,告诉你我的意思:
您可以在我从以下网站获取此图片的博客文章中找到一个分解和参考指南:
http://www.simplygoodcode.com/2015/11/the-difference-between-service-provider-and-factory-in-angularjs/
下面是一些关于服务和工厂的更多例子,这些例子可能有助于发现它们之间的区别。基本上,服务有"new…"调用,它已经被实例化了。工厂没有自动实例化。
基本实例返回具有单个方法的类对象以下是一个具有单一方法的服务:
1 2 3 | angular.service('Hello', function () { this.sayHello = function () { /* ... */ }; }); |
这是一个工厂,它返回一个具有以下方法的对象:
1 2 3 4 5 | angular.factory('ClassFactory', function () { return { sayHello: function () { /* ... */ } }; }); |
返回值
返回数字列表的工厂:
1 2 3 4 5 | angular.factory('NumberListFactory', function () { return [1, 2, 3, 4, 5]; }); console.log(NumberListFactory); |
返回数字列表的服务:
1 2 3 4 5 | angular.service('NumberLister', function () { this.numbers = [1, 2, 3, 4, 5]; }); console.log(NumberLister.numbers); |
两种情况下的输出是相同的,即数字列表。
高级示例使用工厂的"类"变量在本例中,我们定义了一个CounterFactory,它递增或递减一个计数器,您可以获取当前计数或创建了多少CounterFactory对象:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | angular.factory('CounterFactory', function () { var number_of_counter_factories = 0; // class variable return function () { var count = 0; // instance variable number_of_counter_factories += 1; // increment the class variable // this method accesses the class variable this.getNumberOfCounterFactories = function () { return number_of_counter_factories; }; this.inc = function () { count += 1; }; this.dec = function () { count -= 1; }; this.getCount = function () { return count; }; } }) |
我们使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | var people_counter; var places_counter; people_counter = new CounterFactory(); console.log('people', people_counter.getCount()); people_counter.inc(); console.log('people', people_counter.getCount()); console.log('counters', people_counter.getNumberOfCounterFactories()); places_counter = new CounterFactory(); console.log('places', places_counter.getCount()); console.log('counters', people_counter.getNumberOfCounterFactories()); console.log('counters', places_counter.getNumberOfCounterFactories()); |
此代码的输出为:
1 2 3 4 5 6 | people 0 people 1 counters 1 places 0 counters 2 counters 2 |
"工厂"和"服务"是在角度上执行DI(依赖注入)的不同方式。
所以当我们使用"服务"定义DI时,如下面的代码所示。这将创建"logger"对象的新全局实例,并将其注入到函数中。
1 | app.service("Logger", Logger); // Injects a global object |
当使用"工厂"定义DI时,它不会创建实例。它只是传递方法,稍后使用者必须在内部为对象实例调用工厂。
1 | app.factory("Customerfactory", CreateCustomer); |
下面是一个简单的图像,它直观地显示了"服务"的DI处理与"工厂"的不同。
当我们想要根据场景创建不同类型的对象时,应该使用工厂。例如,根据场景的不同,我们希望创建一个简单的"客户"对象,或"地址"对象为"客户",或"电话"对象为"客户"。这是对这一段的详细解释
当我们有要注入的实用程序或共享函数(如实用程序、记录器、错误处理程序等)时,应该使用服务。
service-style:(可能是最简单的一个)返回实际的函数:用于共享实用程序函数,这些函数只需将()附加到注入的函数引用即可调用。
AngularJS中的服务是包含一组函数的单例JavaScript对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | var myModule = angular.module("myModule", []); myModule.value ("myValue" ,"12345"); function MyService(myValue) { this.doIt = function() { console.log("done:" + myValue; } } myModule.service("myService", MyService); myModule.controller("MyController", function($scope, myService) { myService.doIt(); }); |
工厂风格:(更复杂但更复杂)返回函数的返回值:在Java中实例化一个对象,比如新的对象()。
工厂是一个创建值的函数。当服务、控制器等需要从工厂注入值时,工厂会根据需要创建值。一旦创建,该值将被重新用于需要注入的所有服务、控制器等。
1 2 3 4 5 6 7 8 9 10 11 12 | var myModule = angular.module("myModule", []); myModule.value("numberValue", 999); myModule.factory("myFactory", function(numberValue) { return"a value:" + numberValue; }) myModule.controller("MyController", function($scope, myFactory) { console.log(myFactory); }); |
provider-style:(完整的、可配置的版本)返回函数$get-function:configurable的输出。
AngularJS中的提供者是您可以创建的最灵活的工厂形式。除了使用provider()函数之外,您还可以像使用服务或工厂一样使用模块注册提供程序。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | var myModule = angular.module("myModule", []); myModule.provider("mySecondService", function() { var provider = {}; var config = { configParam :"default" }; provider.doConfig = function(configParam) { config.configParam = configParam; } provider.$get = function() { var service = {}; service.doService = function() { console.log("mySecondService:" + config.configParam); } return service; } return provider; }); myModule.config( function( mySecondServiceProvider ) { mySecondServiceProvider.doConfig("new config param"); }); myModule.controller("MyController", function($scope, mySecondService) { $scope.whenButtonClicked = function() { mySecondService.doIt(); } }); |
舍尔科夫
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | <!DOCTYPE html> <html ng-app="app"> <head> <script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.1/angular.min.js"> <meta charset=utf-8 /> JS Bin </head> <body ng-controller="MyCtrl"> {{serviceOutput}} <br/><br/> {{factoryOutput}} <br/><br/> {{providerOutput}} var app = angular.module( 'app', [] ); var MyFunc = function() { this.name ="default name"; this.$get = function() { this.name ="new name" return"Hello from MyFunc.$get(). this.name =" + this.name; }; return"Hello from MyFunc(). this.name =" + this.name; }; // returns the actual function app.service( 'myService', MyFunc ); // returns the function's return value app.factory( 'myFactory', MyFunc ); // returns the output of the function's $get function app.provider( 'myProv', MyFunc ); function MyCtrl( $scope, myService, myFactory, myProv ) { $scope.serviceOutput ="myService =" + myService; $scope.factoryOutput ="myFactory =" + myFactory; $scope.providerOutput ="myProvider =" + myProv; } </body> </html> |
杰斯宾
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | <!DOCTYPE html> <html ng-app="myApp"> <head> <script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.1/angular.min.js"> <meta charset=utf-8 /> JS Bin </head> <body> {{hellos}} var myApp = angular.module('myApp', []); //service style, probably the simplest one myApp.service('helloWorldFromService', function() { this.sayHello = function() { return"Hello, World!" }; }); //factory style, more involved but more sophisticated myApp.factory('helloWorldFromFactory', function() { return { sayHello: function() { return"Hello, World!" } }; }); //provider style, full blown, configurable version myApp.provider('helloWorld', function() { this.name = 'Default'; this.$get = function() { var name = this.name; return { sayHello: function() { return"Hello," + name +"!" } } }; this.setName = function(name) { this.name = name; }; }); //hey, we can configure a provider! myApp.config(function(helloWorldProvider){ helloWorldProvider.setName('World'); }); function MyCtrl($scope, helloWorld, helloWorldFromFactory, helloWorldFromService) { $scope.hellos = [ helloWorld.sayHello(), helloWorldFromFactory.sayHello(), helloWorldFromService.sayHello()]; } </body> </html> |
杰西德
这就是我如何理解它们在设计模式方面的区别:
服务:返回一个类型,该类型将被更新以创建该类型的对象。如果使用Java类比,则服务返回Java类定义。
工厂:返回可立即使用的具体对象。在Java类比中,工厂返回一个Java对象。
经常让人(包括我自己)感到困惑的部分是,当您在代码中注入服务或工厂时,它们可以以相同的方式使用,在这两种情况下,您在代码中得到的是一个具体的对象,您可以立即调用它。这意味着在服务的情况下,Angular代表您在服务声明中称为"新"。我认为这是一个复杂的概念。
AngularJS服务vs工厂
1 2 3 | module.service( 'serviceName', function ); module.factory( 'factoryName', function ); |
将
当声明
在下面的示例中,我们以两种不同的方式定义
AngularJS.服务
1 2 3 4 5 6 7 8 9 | module.service('MyService', function() { this.method1 = function() { //.. } this.method2 = function() { //.. } }); |
安格拉尔工厂
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | module.factory('MyService', function() { var factory = {}; factory.method1 = function() { //.. } factory.method2 = function() { //.. } return factory; }); |
基本区别在于,提供程序允许将原语(非对象)、数组或回调函数值设置到工厂声明的变量中,因此,如果返回对象,则必须显式声明并返回该对象。
另一方面,服务只能用于将服务声明变量设置为对象,这样我们就可以避免对象的显式创建和返回,而另一方面,它允许使用这个关键字。
或者简而言之,"提供者是一种更通用的形式,而服务仅限于对象"。
我们可以这样定义服务:
1 2 3 4 5 | app.service('MyService', function () { this.sayHello = function () { console.log('hello'); }; }); |
现在和工厂一样:
1 2 3 4 5 6 7 | app.factory('MyService', function () { return { sayHello: function () { console.log('hello'); } } }); |
同样,
好吧,您可能会看到,我们不是在工厂中使用它,而是返回一个对象文本。为什么会这样?事实证明,服务是一个构造函数函数,而工厂不是。在这个角度世界的深处,有这样的代码,当服务构造函数函数被实例化时,它调用object.create()。然而,工厂函数实际上只是一个被调用的函数,这就是为什么我们必须显式返回一个对象。
这将是了解服务与工厂与供应商的最佳简短答案。
来源:https://groups.google.com/forum/!msg/angular/56sdorweqg/huzsosmvkv4j/角型/56sdorweqg/huzsosmvkv4j
在这里,Ben通过一个演示说了什么http://jsbin.com/ohamub/1/edit?输出HTML
"代码中有一些说明主要差异的注释,但我将在这里对它们进行一些扩展。作为一个说明,我只是想了解这个问题,所以如果我说了什么错误的话,请告诉我。
服务
语法:module.service("servicename",函数);
结果:将servicename声明为可注入参数时,将提供传递给module.service的实际函数引用。
用法:对于共享实用程序函数很有用,这些函数可以通过简单地将()附加到注入的函数引用来调用。也可以使用injectedarg.call(this)或类似方法运行。
工厂
语法:module.factory("factoryname",函数);
结果:将FactoryName声明为可注入参数时,将通过调用传递给module.factory的函数引用返回值。
用法:对于返回"class"函数很有用,该函数随后可以被新建以创建实例。
提供者
语法:module.provider("providername",函数);
结果:当将providername声明为可注入参数时,将通过调用传递给module.provider的函数引用的$get方法返回值。
用法:对于返回"class"函数很有用,该函数可以是新的,用于创建实例,但在注入之前需要某种配置。可能对可跨项目重用的类有用?还是有点模糊。"本
有一段时间我有点困惑,我正在尽力在这里提供一个简单的解释。希望这会有所帮助!
唯一的区别是,您希望如何初始化服务。
两个都是单人的
1 | var app = angular.module('app', []); |
工厂应用工厂(
如果您希望使用返回值的函数初始化服务,则必须使用此
例如
1 2 3 4 5 6 7 8 9 | function myService() { //return what you want var service = { myfunc: function (param) { /* do stuff */ } } return service; } app.factory('myService', myService); |
注入此服务时(例如,向控制器注入):
- Angular将调用给定的函数(作为
myService() 返回对象 - singleton—只调用一次,存储并传递同一对象。
服务应用服务(
如果要从构造函数函数(使用
例如
1 2 3 4 5 | function myService() { this.myfunc: function (param) { /* do stuff */ } } app.service('myService', myService); |
注入此服务时(例如,向控制器注入):
- 用你给定的函数(如
new myService() )返回物体的角度。 - singleton—只调用一次,存储并传递同一对象。
注:如果您使用
示例-演示
- 角度服务与工厂
- 角度服务与工厂(带路线)
多亏了帕斯卡·普雷希特的一篇博文,这才帮助我理解了两者之间的区别。
服务是模块上的一种方法,它使用一个名称和一个定义服务的函数。您可以在其他组件(如控制器、指令和过滤器)中注入和使用该特定服务。工厂是模块上的一种方法,它还具有定义工厂的名称和函数。我们也可以像使用服务一样注入和使用它。
使用new创建的对象将其构造函数函数的Prototype属性的值用作原型,因此我找到了调用object.create()的角度代码,我认为它在实例化时是服务构造函数函数。然而,工厂函数实际上只是一个被调用的函数,这就是为什么我们必须为工厂返回一个对象文本。
这是我为工厂找到的角1.5代码:
1 2 3 4 5 6 7 | var needsRecurse = false; var destination = copyType(source); if (destination === undefined) { destination = isArray(source) ? [] : Object.create(getPrototypeOf(source)); needsRecurse = true; } |
factory()函数的角度源代码段:
1 2 3 4 5 | function factory(name, factoryFn, enforce) { return provider(name, { $get: enforce !== false ? enforceReturnValue(name, factoryFn) : factoryFn }); } |
它接受传递的名称和工厂函数,并返回具有相同名称的提供程序,该提供程序具有$GET方法,这是我们的工厂函数。每当您向注入器请求特定的依赖项时,它基本上通过调用$get()方法向相应的提供者请求该服务的实例。这就是为什么在创建提供程序时需要$get()。
这是角度1.5的服务代码。
1 2 3 4 5 | function service(name, constructor) { return factory(name, ['$injector', function($injector) { return $injector.instantiate(constructor); }]); } |
事实证明,当我们调用service()时,它实际上调用了factory()!然而,它并不是像现在一样将我们的服务构造函数传递给工厂。它还传递一个函数,该函数要求注入器通过给定的构造函数实例化一个对象。
换句话说,如果我们在某个地方注入myservice,代码中发生的事情是:
1 | MyServiceProvider.$get(); // return the instance of the service |
为了再次重申它,服务调用一个工厂,这是对应提供者上的$get()方法。此外,$injector.instantiate()是最终使用构造函数函数调用object.create()的方法。这就是为什么我们在服务中使用"这个"。
对于ES5,不管我们使用哪一个:service()还是factory(),它总是一个被调用的工厂,它为我们的服务创建一个提供者。
不过,您也可以对服务做同样的事情。然而,服务是一个构造函数函数,这并不妨碍我们返回对象文本。所以我们可以获取我们的服务代码并以一种基本上与我们的工厂完全相同的方式来编写它,换句话说,您可以将服务作为工厂来编写以返回对象。
为什么大多数人建议使用工厂而不是服务?这是我从PawelKozlowski的书中看到的最好的答案:用AngularJS掌握Web应用程序开发。
The factory method is the most common way of getting objects into
AngularJS dependency injection system. It is very flexible and can
contain sophisticated creation logic. Since factories are regular
functions, we can also take advantage of a new lexical scope to
simulate"private" variables. This is very useful as we can hide
implementation details of a given service."
- 使用工厂,您实际上在工厂内部创建了一个对象并将其返回。
- 对于服务,您只有一个标准函数,它使用docx1〔0〕关键字定义功能。
- 对于提供者,您定义了一个
$get ,它可以用来获取返回的对象。数据。
AngularJS中有三种处理业务逻辑的方法:(灵感来自Yaakov的Coursera AngularJS课程),它们是:
这里我们只谈服务和工厂
服务:
Syntax:
App.JS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | var app = angular.module('ServiceExample',[]); var serviceExampleController = app.controller('ServiceExampleController', ServiceExampleController); var serviceExample = app.service('NameOfTheService', NameOfTheService); ServiceExampleController.$inject = ['NameOfTheService'] //very important as this protects from minification of js files function ServiceExampleController(NameOfTheService){ serviceExampleController = this; serviceExampleController.data = NameOfTheService.getSomeData(); } function NameOfTheService(){ nameOfTheService = this; nameOfTheService.data ="Some Data"; nameOfTheService.getSomeData = function(){ return nameOfTheService.data; } } |
索引文件
1 | {{serviceExample.data}} |
服务的主要特点:
延迟实例化:如果不注入服务,则永远不会实例化它。所以要使用它,你必须将它注入到一个模块中。
单件:如果它被注入到多个模块中,那么所有模块都只能访问一个特定的实例。这就是为什么,在不同的控制器之间共享数据非常方便。
工厂
现在让我们来谈谈安加拉的工厂
首先,让我们看一下语法:
App.JS:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | var app = angular.module('FactoryExample',[]); var factoryController = app.controller('FactoryController', FactoryController); var factoryExampleOne = app.factory('NameOfTheFactoryOne', NameOfTheFactoryOne); var factoryExampleTwo = app.factory('NameOfTheFactoryTwo', NameOfTheFactoryTwo); //first implementation where it returns a function function NameOfTheFactoryOne(){ var factory = function(){ return new SomeService(); } return factory; } //second implementation where an object literal would be returned function NameOfTheFactoryTwo(){ var factory = { getSomeService : function(){ return new SomeService(); } }; return factory; } |
现在在控制器中使用上述两个:
1 2 3 4 5 | var factoryOne = NameOfTheFactoryOne() //since it returns a function factoryOne.someMethod(); var factoryTwo = NameOfTheFactoryTwo.getSomeService(); //accessing the object factoryTwo.someMethod(); |
工厂特点:
这种类型的服务遵循工厂设计模式。工厂可以被认为是创建新对象或方法的中心位置。
这不仅产生了单例服务,还产生了可定制的服务。
有关简短解释,请参阅https://stackoverflow.com/a/26924234/5811973。
有关详细说明,请参阅https://stackoverflow.com/a/1566649/5811973。
同样来自AngularJS文档:
你可以理解这个类比的区别-考虑一个将返回一些值的普通函数和一个将使用new关键字实例化的构造函数函数之间的区别。因此,创建工厂就像创建一个将返回一些值(原语或对象)的普通函数,而创建服务就像正在创建构造函数(oo类),我们可以使用new关键字创建其实例。唯一需要注意的是,当我们使用服务方法创建服务时,它将使用AngularJS支持的依赖注入机制自动创建它的实例。