JavaScript 中制作函数副本的技术如何工作(Storybook 示例)
How does technique for making a copy of a function works in JavaScript (Storybook example)
Storybook recommends 复制函数的技巧:
const Template = args => <Task {...args} />;
export const Default = Template.bind({});
它允许每个导出的故事设置自己的属性,但使用相同的实现。
我理解结果,但不明白为什么它必须将函数绑定到一个空对象 {}
您提供的 link 中的完整相关代码是:
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 = {...}
,在每个副本和原始版本(此处未使用)上有不同的定义。
编辑
正如 link 的文档中所说:
Template.bind({})
is a standard JavaScript technique for making a copy
of a function. We use this technique to allow each exported story to
set its own properties, but use the same implementation.
上面的代码片段在箭头函数上使用了 bind()
:
const Template = args => <Task {...args} />;
export const Default = Template.bind({});
在箭头函数上使用 bind
根本不会修改箭头函数的行为,因为箭头函数的 this
始终是定义箭头函数的范围。
MDN 建议不要在箭头函数上使用 bind
MDN - Arrow function expressions: call, apply and bind
The call, apply and bind methods are NOT suitable for Arrow functions -- as they were designed to allow methods to execute within different scopes -- because Arrow functions establish "this" based on the scope the Arrow function is defined within.
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
。
Storybook recommends 复制函数的技巧:
const Template = args => <Task {...args} />;
export const Default = Template.bind({});
它允许每个导出的故事设置自己的属性,但使用相同的实现。
我理解结果,但不明白为什么它必须将函数绑定到一个空对象 {}
您提供的 link 中的完整相关代码是:
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 = {...}
,在每个副本和原始版本(此处未使用)上有不同的定义。
编辑
正如 link 的文档中所说:
Template.bind({})
is a standard JavaScript technique for making a copy of a function. We use this technique to allow each exported story to set its own properties, but use the same implementation.
上面的代码片段在箭头函数上使用了 bind()
:
const Template = args => <Task {...args} />;
export const Default = Template.bind({});
在箭头函数上使用 bind
根本不会修改箭头函数的行为,因为箭头函数的 this
始终是定义箭头函数的范围。
MDN 建议不要在箭头函数上使用 bind
MDN - Arrow function expressions: call, apply and bind
The call, apply and bind methods are NOT suitable for Arrow functions -- as they were designed to allow methods to execute within different scopes -- because Arrow functions establish "this" based on the scope the Arrow function is defined within.
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
。