Maison >interface Web >js tutoriel >Exemple de code détaillé pour les fonctions d'usine en JavaScript
La fonction dite d'usine signifie que ces fonctions intégrées sont toutes des objets de classe. Lorsque vous les appelez, vous créez en fait une instance de classe. Cet article présente principalement la fonction d'usine JavaScript. Les amis qui en ont besoin peuvent se référer à
Lors de l'apprentissage de jQuery, nous le faisons souvent. voir le concept de « fonction d'usine », alors qu'est-ce qu'une « fonction d'usine » exactement ? Jetons un coup d'œil au concept : "La fonction dite d'usine signifie que ces fonctions intégrées sont toutes des objets de classe. Lorsque vous les appelez, vous créez en fait une instance de classe." Cela signifie que lorsque j'appelle cette fonction, je crée en fait un objet en utilisant la classe, puis je renvoie l'objet. Puisque Javascript lui-même n'est pas un langage strictement orienté objet (n'inclut pas les classes), en fait, Javascript n'a pas de "fonction d'usine" stricte, mais en Javascript, nous pouvons utiliser des fonctions pour simuler des classes.
Nous créons d'abord un objet via le mot-clé new, et obj est équivalent à une instance de Object. Nous instancions un objet via la classe, puis donnons à l'objet les attributs correspondants et enfin renvoyons l'objet. On peut créer des objets en appelant cette fonction. Dans ce cas, la fonction factory est en fait facile à comprendre :
1, c'est une fonction.
2, qui sert à créer des objets.
3. C'est comme une usine. Les fonctions "produites" sont toutes des "pièces standards" (avec les mêmes attributs)
Vous ne pouvez pas devenir un JavaScript sans apprendre les fonctions et les objets. Les programmeurs, et lorsqu'ils sont utilisés ensemble, sont des éléments de base, nous devons commencer par un paradigme d'objet puissant appelé composition. Aujourd'hui, nous examinons quelques modèles idiomatiques d'utilisation de fonctions d'usine pour composer des fonctions, des objets et des promesses. Le Mode combiné organise un lot de sous-objets dans une structure arborescente, et une commande de niveau supérieur fera fonctionner tous les objets de l'arborescence. Lorsqu'une fonction renvoie un objet, nous l'appelons une fonction d'usine.
Regardons un exemple simple.
function createJelly() { return { type: 'jelly', colour: 'red' scoops: 3 }; }
Ci-dessous nous vous le présenterons à travers quelques exemples.
Chaque fois que nous appelons cette fonction d'usine, elle renverra une nouvelle instance d'objet Jelly. La chose importante à noter est que nous n'avons pas besoin de faire précéder le nom de la fonction d'usine par create , mais cela rend l'intention de la fonction plus claire pour les autres. La même chose est vraie pour l'attribut type, mais il nous aide généralement à différencier les objets de notre programme.
1. Fonction usine avec paramètres
Comme toutes les fonctions, nous pouvons définir notre fonction usine (glace glace) à travers des paramètres, cela peut être utilisé pour changer le Modèle de l'objet renvoyé.
function createIceCream(flavour='Vanilla') { return { type: 'icecream', scoops: 3, flavour } }
En théorie, vous pourriez utiliser des fonctions d'usine avec des centaines d'arguments pour renvoyer des envoyés très envoyés d'objets profondément imbriqués, mais comme nous le verrons, ce n'est pas du tout l'essence de la composition.
2. Fonction d'usine combinée
Définir une autre fonction d'usine au sein d'une fonction d'usine peut nous aider à diviser la fonction d'usine complexe en plus petites, fragments réutilisables.
Par exemple, nous pouvons créer une fonction d'usine de dessert (dessert), définie par les fonctions d'usine précédentes jelly (gelée) et icecream (crème glacée).
function createDessert() { return { type: 'dessert', bowl: [ createJelly(), createIceCream() ] }; }
Nous pouvons combiner des fonctions d'usine pour construire des objets arbitrairement complexes, ce qui ne nous oblige pas à utiliser new ou this en combinaison. Les objets peuvent être représentés par la relation has-a (has) au lieu de is-a (is). En d'autres termes, il peut être implémenté en utilisant la composition au lieu de hériter .
// A trifle *is a* dessert 蛋糕*是*甜点 function Trifle() { Dessert.apply(this, arguments); } Trifle.prototype = Dessert.prototype; // 或者 class Trifle extends Dessert { constructor() { super(); } }Nous pouvons exprimer la même signification en utilisant le mode combinaison.
// A trifle *has* layers of jelly, custard and cream. It also *has a* topping. // 蛋糕 *有* 果冻层,奶酪层和奶油层,顶部还 *有* 装饰配料。 function createTrifle() { return { type: 'trifle', layers: [ createJelly(), createCustard(), createCream() ], topping: createAlmonds() }; }
3. Fonction d'usine asynchrone
Toutes les usines ne renverront pas les données immédiatement. Par exemple, certains doivent d’abord obtenir les données. Dans ces cas, nous pouvons renvoyer des promesses pour définir les fonctions d'usine.function getMeal(menuUrl) { return new Promise((resolve, reject) => { fetch(menuUrl) .then(result => { resolve({ type: 'meal', courses: result.json() }); }) .catch(reject); }); }Cette indentation profondément imbriquée peut rendre les usines asynchrones difficiles à lire et à tester. Il est souvent utile de les diviser en plusieurs usines différentes, qui peuvent s'écrire ainsi.
function getMeal(menuUrl) { return fetch(menuUrl) .then(result => result.json()) .then(json => createMeal(json)); } function createMeal(courses=[]) { return { type: 'meal', courses }; }Bien sûr, nous pouvons utiliser la
fonction de rappel, mais nous avons déjà des outils comme Promise.all qui renvoient des promesses pour définir des fonctions d'usine.
function getWeeksMeals() { const menuUrl = 'jsfood.com/'; return Promise.all([ getMeal(`${menuUrl}/monday`), getMeal(`${menuUrl}/tuesday`), getMeal(`${menuUrl}/wednesday`), getMeal(`${menuUrl}/thursday`), getMeal(`${menuUrl}/friday`) ]); }Nous utilisons get au lieu de create comme convention de dénomination pour montrer que ces usines effectuent un travail asynchrone et renvoient des promesses.
4.函数和方法
到目前为止,我们还没有看到任何工厂用方法返回对象,这是故意的。这是因为一般来说,我们不需要这么做。工厂允许我们从计算中分离我们的数据。这意味着我们总是能够将对象序列化为JSON,这对于在会话之间持久化,通过HTTP或WebSockets发送它们,并将它们放入数据存储很重要。
例如,不是在 jelly(果冻) 对象上定义 eat 方法,我们可以定义一个新的函数,它接受一个对象作为参数并返回一个修改的版本。
function eatJelly(jelly) { if(jelly.scoops > 0) { jelly.scoops -= 1; } return jelly; }
一点点句法帮助使这是一个可行的模式,那些喜欢编程而不改变数据结构的人。对于那些喜欢编程而不改变数据结构的人来说,使用 ES6 的 ... 语法 是一个可行的模式。
function eat(jelly) { if(jelly.scoops > 0) { return { ...jelly, scoops: jelly.scoops - 1 }; } else { return jelly; } }
现在,不是这样写:
import { createJelly } from './jelly'; createJelly().eat();
而是这样写
import { createJelly, eatJelly } from './jelly'; eatJelly(createJelly());
最终结果是一个函数,它接受一个对象并返回一个对象。我们称之为返回对象的函数是什么? 一个工厂!
5.高级工厂
将工厂传递给 高阶函数 ,这将给我们带来巨大的控制力。例如,我们可以使用这个概念来创建一个增强的对象。
function giveTimestamp(factory) { return (...args) => { const instance = factory(...args); const time = Date.now(); return { time, instance }; }; } const createOrder = giveTimestamp(function(ingredients) { return { type: 'order', ingredients }; });
这个增强的对象采用一个现有工厂,并将其包装以创建返回带有时间戳实例的工厂。或者,如果我们想要确保一个工厂返回不可变的对象,我们可以用 freezer 来增强它。
function freezer(factory) { return (...args) => Object.freeze(factory(...args))); } const createImmutableIceCream = freezer(createIceCream); createImmutableIceCream('strawberry').flavour = 'mint'; // Error!
6.结论
作为一个 聪明的程序员 曾经说过:从没有抽象比错误的抽象更容易回收。JavaScript项目有一个趋势,变得难以测试和重构,因为我们经常鼓励使用复杂的抽象层。原型和类实现一个简单的想法使用复杂和不人性的工具,如 new 和 this ,即使现在,这仍然引起 各种各样的困惑 -几年后他们被添加到语言。对象和函数对于来自大多数语言背景的程序员来说是有意义的,并且都是JavaScript中的原始类型,所以可以说工厂不是抽象的!对象和函数对来自大多数背景的程序员都有意义,并且都是JavaScript中的原始类型,所以可以说工厂不是抽象的!使用这些简单的构建块使得我们的代码对于没有经验的程序员更加友好,这绝对是我们应该关心的事情。工厂鼓励我们用原始数据来模拟复杂和异步数据,原始数据具有组合的自然能力,而不强迫我们去做一些高级抽象。 当我们坚持简单时,JavaScript更甜蜜!
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!