Factory Function有什么用

2022-01-17 21:11:28 浏览数 (1)

昨天就在看这方面内容,不过没有吃透。ES6中出现了class关键字声明一个类,也可以通过extends去继承一个类,越来越像它的名字了。

在ES6普及应用之前,存在许多种构造对象的方法,factory function只是其中一种。

Factory Function:当一个function返回object时, 称它为factory function. 一个最简单的例子

代码语言:javascript复制
function createJelly() {
 return {
   type: 'jelly',
   colour: 'red'
   scoops: 3
 };}

当我们每次调用这个方法,它都会返回一个新的引用(new instance)。

var jelly = createJelly();

jelly.colour ------> red

这不就是创建一个对象吗?没错,这是它最明显的一个功能。

与controller function的区别

给出两种方法的实现对比:

1. 两种方法的功能是相同的,都是创建了一个Rabbit对象。

2. 第二种使用new关键字。

The object is created by literal on the left, and by new on the right.

3. 继承功能,factory method使用rabbit=Animal() 去获得父类对象,controller使用Animal.apply(this, argument)。

两者只是语法上存在细微区别,Choose the one you'd prefer.

author: llya Kantor link: http://javascript.info/tutorial/factory-constructor-pattern

Private/protected method

在方法内部返回值前,定一个变量和方法都是私有的

代码语言:javascript复制
function Bird(name) {
var speed = 100                    // private prop
function openWings() { /* ... */ } // private methodreturn {
fly: function() {
openWings()
this.move()
},
move: function() { /*...*/ }
}
}

但是这样的写法存在一个问题,

公共方法可以被另一个公共方法调用,如this.move(),不能被私有方法调用。

如果想在private method方法内调用对象的某个方法或参数是没办法的,因为local function没有引用指向新对象。

解决方法如下:

代码语言:javascript复制
function Bird(name) {
function doFly() {
openWings()
self.move()
} // private methodvar self ={
fly: function() { doFly() },
move: function() { /*...*/ }
}
return self
}

以下内容翻译自

author: Dan Prince link: https://www.sitepoint.com/factory-functions-javascript/

Parameterized Factory Functions(参数化方法)

代码语言:javascript复制
function createIceCream(flavour='Vanilla') {
 return {
   type: 'icecream',
   scoops: 3,
   flavour  }}

理论上,可以使用很多的参数来构造参数化方法,这样能返回非常具体(very specific)并且深层嵌套(deeply nested)的对象。

Composable Factory Functions(组件化方法)

Defining one factory in terms of another.

返回一个对象(内部是返回对象的方法),可以帮助我们把复杂的factories分解成更小、可重用的碎片。

代码语言:javascript复制
function createDessert() {
 return {
   type: 'dessert',
   bowl: [
     createJelly(),
     createIceCream()
   ]
 };}

这样可以组建任意复杂的对象,不需要浪费时间创建新的对象。

Async Factory Functions

并不是所有的factories都是立即但会数据。例如:一些函数必须先fetch数据。

代码语言:javascript复制
function getMeal(menuUrl) {
 return new Promise((resolve, reject) => {
   fetch(menuUrl)
     .then(result => {
       resolve({
         type: 'meal',
         courses: result.json()
       });
     })
     .catch(reject);
 });}

这种深层的嵌套让异步工厂难以阅读和测试,它常常可以分解为多个不同的工厂,然后组合它们。

代码语言:javascript复制
function getMeal(menuUrl) {
 return fetch(menuUrl)
   .then(result => result.json())
   .then(json => createMeal(json));}
function createMeal(courses=[]) {
 return {
   type: 'meal',
   courses  };}

当然我们可以使用回调代替,但是我们已经有了像Promise的工具,返回promises的组合工厂。

代码语言:javascript复制
function getWeeksMeals() {
 const menuUrl = 'jsfood.com/'; return Promise.all([
   getMeal(`${menuUrl}/monday`),
   getMeal(`${menuUrl}/tuesday`),
   getMeal(`${menuUrl}/wednesday`),
   getMeal(`${menuUrl}/thursday`),
   getMeal(`${menuUrl}/friday`)
 ]);}

命名约定(naming convention)用get而没有用create,这些工厂do some asynchronous works and return promises.

Functions & Methods

到目前为止,还没有看到任何返回方法对象的工厂(return objects with methods),This is because generally, we don't need to.

工厂允许我们去计算数据,这意味着我们总是可以将objects序列化为JSON,这有利于保持它们之间的session,通过HTTP或者WebSocket协议,并将它们转化为数据存储。

例如:相比于在jelly对象上定义一个eat方法,我们可以定义一个(使用参数并且返回新对象)新方法。

代码语言:javascript复制
function eatJelly(jelly) {
 if(jelly.scoops > 0) {
   jelly.scoops -= 1;
 }
 return jelly;}

使用babel.js中babel-plugin-transform-object-rest-spread插件可以这样写代码:

代码语言:javascript复制
function eat(jelly) {
 if(jelly.scoops > 0) {
   return { ...jelly, scoops: jelly.scoops - 1 };
 } else {
   return jelly;
 }}

插件官网:https://babeljs.io/docs/plugins/transform-object-rest-spread/

github地址:https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-object-rest-spread

如果在对象上定义方法时,是这样调用的:

代码语言:javascript复制
import { createJelly } from './jelly';
createJelly().eat();

现在是这样调用的:

代码语言:javascript复制
import { createJelly, eatJelly } from './jelly';
eatJelly(createJelly());

Conclusion

It’s much easier to recover from no abstraction than the wrong abstraction.

使用这些简单的构建块,使得我们的代码更加友好,Factories 鼓励我们的model复杂和使用原始的异步数据,没有强迫我们去实现高水平的抽象。

国内的相关资料比较少,这些内容翻译总结而来,如果有理解错误的地方请及时提出。

更多相关内容可查看:

1. title: Factory Function in JavaScript

author: Josh Miller

http://atendesigngroup.com/blog/factory-functions-javascript

2. Title: Quick TIp: What Are Factory Functions in JavaScript

Link: https://www.sitepoint.com/factory-functions-javascript/

3.Title: Factory constructor pattern

Link: http://javascript.info/tutorial/factory-constructor-pattern

0 人点赞