原文: http://blog.thoughtram.io/angular/2015/07/07/service-vs-factory-once-and-for-all.html

Service和Factory有什么不同,我应该使用哪个?

这篇文章将讲解service和factory的不同之处,为什么我们喜欢service多过于factory.

Service和Factory的不同之处

在AngularJS中service和factory有什么不同? 我们可以这样定义一个service:

app.service('MyService', function () {
this.sayHello = function () {
console.log('hello');
};
});

.service() 是我们module的一个方法。 有两个参数,第一个参数是服务名,第二个参数是一个function. 可以把Service注入到其他的component中,如controller, directive, filters. 注入方法如下:

app.controller('AppController', function (MyService) {
MyService.sayHello(); // logs 'hello'
});

好了,看看factory是如何做同样的事情的:

app.factory('MyService', function () {
return {
sayHello: function () {
console.log('hello');
};
}
});

.factory() 同样是我们module的一个方法,有两个参数,第一个是factory名,第二个是一个function. 同样factory也可以注入到其他components中. 那么他的不同之处在哪呢?

可以看到在factory中我们没有使用 this , 而是返回一个对象字面量. 为什么这样?因为,service是一个构造函数factory不是. 所以我们在factory的funtion中要显示的返回一个对象.

来看看AngularJS的源代码中的factory函数是怎样的:

function factory(name, factoryFn, enforce) {
return provider(name, {
$get: enforce !== false ? enforceReturnValue(name, factoryFn) : factoryFn
});
}

factory接收一个name, 和factory函数,返回一个同名的provider, $get 是我们的factory函数. 当你获取一个注入,会调用$get()方法向相应的provider请求一个service的实例. 这就是为什么创建provider的时候需要有$get()方法.

换而言之, 当注入MyService时, 后面究竟发生了什么呢:

MyServiceProvider.$get(); // 返回service的实例

现在看看service函数在AngularJS的源代码中是怎么样的:

function service(name, constructor) {
return factory(name, ['$injector', function($injector) {
return $injector.instantiate(constructor);
}]);
}

从代码中看得出来,当调用service()的时候实际上最后调用了factory(). 但是没有直接把service的构造函数传给factory. 而是传递了一个依赖injector的函数,通过这个injector去实例化. 简单的说: service调用了预定义的factory, 最后调用相应的provider的$get()方法. $injector.instantiate() 方法最终调用Object.create(),参数为构造函数. 这就是为什么我们要在service里面使用this.

不论我么使用 service() 还是 factory(), 最终都是一个factory,然后这个factory去调用provider.

使用哪一个?

“serivce和factory的不同如下:”

app.service('myService', function() {

  // service是一个构造函数

  this.sayHello = function(name) {
return "Hi " + name + "!";
};
}); app.factory('myFactory', function() { // factory返回一个对象 return {
sayHello : function(name) {
return "Hi " + name + "!";
}
}
});

是的service是一个构造函数, 然后我们一样可以在这个构造函数中返回对象字面量. 事实上, 在javascript中构造函数可以返回任何你想返回的东西. 所以我们把service写得和factory一样:

app.service('MyService', function () {

  // 我们可以在这加入其它的代码
return {
sayHello: function () {
console.log('hello');
};
}
});

现在factory和service的写法已经一样了. 问题是: 我们该使用哪一个呢?

Service能让我们使用ES6的class

在ES6中我们可以这样定义service:

class MyService {
sayHello() {
console.log('hello');
}
} app.service('MyService', MyService);

ES6 class和ES5中的构造函数是一回事.

[译]AngularJS Service vs Factory - Once and for all的更多相关文章

  1. AngularJs:Service、Factory、Provider依赖注入使用与区别

           本教程使用AngularJS版本:1.5.3        AngularJs GitHub: https://github.com/angular/angular.js/       ...

  2. 跟我学AngularJs:Service、Factory、Provider依赖注入使用与差别

    林炳文Evankaka原创作品. 转载请注明出处http://blog.csdn.net/evankaka        本教程使用AngularJs版本号:1.5.3        AngularJ ...

  3. AngularJS 讲解五, Factory ,Service , Provider

    一. 首先说一下,为什么要引入Factory,Service和Provider这三个Service层. 1.因为我们不应该在controller层写入大量的业务逻辑和持久化数据,controller层 ...

  4. 【AngularJS中的自定义服务service VS factory VS provider】---它们的区别,你知道么?

    在介绍AngularJS自定义服务之前,我们先来了解一下AngularJS~ 学过HTML的人都知道,HTML是一门很好的伪静态文本展示设计的声明式语言,但是,要构建WEB应用的话它就显得乏力了. 而 ...

  5. AngularJS进阶(三十三)书海拾贝之简介AngularJS中使用factory和service的方法

    简介AngularJS中使用factory和service的方法 AngularJS支持使用服务的体系结构"关注点分离"的概念.服务是JavaScript函数,并负责只做一个特定的 ...

  6. AngularJS 1.x系列:AngularJS服务-Service、Factory、Provider、Value及Constant(5)

    1. AngularJS服务 AngularJS可注入类型包括:Service.Factory.Provider.Value及Constant. 2. Service AngularJS Servic ...

  7. AngularJS中service,factory,provider的区别(转载:http://my.oschina.net/tanweijie/blog/295067)

    目录[-] 一.service引导 二.service 1.factory() ‍2.service()‍ ‍3.provider()‍‍ 一.service引导 刚开始学习Angular的时候,经常 ...

  8. AngularJS中service,factory,provider的区别

    一.service引导 刚开始学习Angular的时候,经常被误解和被初学者问到的组件是 service(), factory(), 和 provide()这几个方法之间的差别.This is whe ...

  9. 一次性搞明白 service和factory区别

    原文链接 http://blog.thoughtram.io/angular/2015/07/07/service-vs-factory-once-and-for-all.html 等下,已经有一篇文 ...

随机推荐

  1. poj1113 凸包

    result=对所有点凸包周长+pi*2*L WA了一次,被Pi的精度坑了 以后注意Pi尽可能搞精确一点.Pi=3.14还是不够用 Code: #include<vector> #incl ...

  2. Viewprot meta学习笔记

    viewprot屏幕尺寸,专为移动页面设计 参数 <meta name="viewport" content="height,width,initial-scale ...

  3. HDU #5733 tetrahedron

    tetrahedron 传送门 Time Limit: 2000/1000 MS (Java/Others)   Memory Limit: 65536/65536 K (Java/Others) P ...

  4. Beta版本冲刺第四天 12.10

    一.站立式会议照片: 二.项目燃尽图: Android端 后台 三.项目进展: 成 员 昨天完成任务 今天完成任务 明天要做任务 问题困难 心得体会 胡泽善 日期合理性的判断,一个是用户反馈的查看 管 ...

  5. jQuery知识点总结(第六天)

    今天工作繁忙,晚上又和所谓的'朋友',吃了自助烧烤. 但我内心是很抗拒的,不知为了什么,竟然稀奇古怪的答应了下来,竟要去吃饭.我向来不喜欢去凑热闹,特别是和志趣不投的人在一起吃,对方所说的话,自己根本 ...

  6. linux中运维相关命令

    1.awk 可以参考:http://www.itshouce.com.cn/linux/linux-awk.html 1.1 常见语法 cat test.txt | awk 'BEGIN{print ...

  7. 从Paxos到ZooKeeper-三、ZooKeeper的典型应用场景

    ZooKeeper是一个典型的发布/订阅模式的分布式数据管理与协调框架,开发人员可以使用它来进行分布式数据的发布与订阅.另一方面,通过对ZooKeeper中丰富的数据节点类型进行交叉使用,配合Watc ...

  8. JAVA jdbc获取数据库连接

    JDBC获取数据库连接的帮助类 import java.io.InputStream; import java.sql.Connection; import java.sql.DriverManage ...

  9. Jint .net平台的javascript引擎

    使用需求 有时候一段Javascript代码写的很棒,而我们又无法将之翻译成.net或翻译之成本很高的时候 我们就可以使用Jint引擎来运行Javascript代码,来得到我们想要的结果 或者上 ht ...

  10. DecimalFormat类

    DecimalFormat类也是Format的一个子类,主要作用是格式化数字. 在格式化数字的时候比直接使用NumberFormat更加方便,因为可以直接指定按用户自定义的方式进行格式化操作,与Sim ...