#javascript #ecmascript-6 #storybook
#javascript #ecmascript-6 #сборник рассказов
Вопрос:
Сборник рассказов рекомендует технику создания копии функции:
const Template = args => <Task {...args} />;
export const Default = Template.bind({});
Это позволяет каждой экспортируемой истории устанавливать свои собственные свойства, но использовать ту же реализацию.
Я понимаю результат, но не понимаю, почему он должен привязывать функцию к пустому объекту {}
Ответ №1:
Полный соответствующий код из предоставленной вами ссылки:
import React from 'react';
import Task from './Task';
export default {
component: Task,
title: 'Task',
};
const Template = args => <Task {...args} />;
export const Default = Template.bind({});
Default.args = {
task: {
id: '1',
title: 'Test Task',
state: 'TASK_INBOX',
updatedAt: new Date(2018, 0, 1, 9, 0),
},
};
export const Pinned = Template.bind({});
Pinned.args = {
task: {
...Default.args.task,
state: 'TASK_PINNED',
},
};
Использование Template.bind({})
позволяет определять дополнительные элементы, такие как Default.args = {...}
, по-разному в каждой копии и в оригинале (здесь не используется).
Редактировать
Как уже было сказано в документах по ссылке:
Template.bind({})
это стандартная техника JavaScript для создания копии функции. Мы используем эту технику, чтобы позволить каждой экспортируемой истории устанавливать свои собственные свойства, но использовать ту же реализацию.
Комментарии:
1. Это:
Template.bind({}) is a standard JavaScript technique for making a copy of a function.
неверно. bind не копирует функцию. Он создает функцию, которая оборачивает исходную функцию.
Ответ №2:
Приведенный выше фрагмент кода используется bind()
для функции со стрелкой:
const Template = args => <Task {...args} />;
export const Default = Template.bind({});
Использование bind
функции со стрелкой вообще не изменяет поведение функции со стрелкой, поскольку this
функция со стрелкой всегда будет областью, в которой была определена функция со стрелкой.
MDN рекомендует не использовать bind
в функциях со стрелками выражения функций MDN — Arrow: call, apply и bind
Методы call, apply и bind НЕ подходят для функций со стрелками — поскольку они были разработаны, чтобы позволить методам выполняться в разных областях — потому что функции со стрелками устанавливают «это» на основе области, в которой определена функция со стрелками.
const arrowFn = () => {
console.log('this.foo:', this.foo);
};
window.foo = 'window.foo';
const myObj = {
foo: 'myObj.foo'
};
const boundFn = arrowFn.bind(myObj);
arrowFn(); // 'window.foo'
boundFn(); // 'window.foo'
Поскольку bind
невозможно изменить функцию со стрелкой, единственная полезная вещь bind
, которую мы делаем в этом примере выше, — это создание новой функции-оболочки, которая может иметь свои собственные уникальные свойства.
Поэтому код из предоставленного примера:
const Template = (...args) => {};
const Default = Template.bind({});
Default.args = {...};
может быть заменен на:
const Template = (...args) => {};
Default = function () { Template(...arguments); }
Default.args = {...};
Преимущество этого второго шаблона в том, что он не используется bind
нестандартным способом.
Комментарии:
1. Это неверно ни в одном из утверждений:
bind
не переносится в традиционную функцию, выполненное сравнение неверно, второй шаблон не лучше: на самом деле это другое решение (немного менее оптимизированное) и может работать не так, как ожидалось, во всех ситуациях.2. @emi — Спасибо за комментарии. Я отредактировал ответ. Несмотря на то, что исходный пример «работает», я все же утверждаю, что
bind
следует избегать использования функции со стрелкой (как указано в MDN).3.
I still submit that using bind on an arrow function should be avoided (as stated in MDN)
Это применимо только тогда, когда функция используетthis
, что не так.4. Примечание: вопрос специфичен для сборника рассказов, который
this
не является частью спецификаций иbind
используется хорошо документированным способом.5. @emi — С практической точки зрения документирование нестандартного шаблона менее предпочтительно, чем использование другого шаблона стандартным способом.