1. 什么是Function#bind
和独立的bind
功能?
Function#bind
致电Function#bind
创建一个永远绑定到作为第一个参数传递的上下文的新函数。Function#bind
作为函数上的方法。也就是说,您只能绑定以下功能Function#bind
被调用。
let str = 'Hello, World!'
let fn = () => console.log(this)
// Bind the `this` to be `str`
let boundFn = fn.bind(str)
boundFn() // => 'Hello, World!'
// Attempt re-bind:
boundFn = fn.bind('new str')
boundFn() // => 'Hello, World!'
______
Function#call
Function#call
不同于Function#bind
在那它executes具有上下文和给定任何其他参数的给定函数。它不返回新的绑定函数。
let str = 'Hello, '
let fn = (who) => console.log(this + who)
fn.call(str, 'World!') // => 'Hello, World!'
______
通过引用传递函数会丢失其上下文
当我们通过引用传递函数时,我们会失去它的上下文。在这种情况下,这意味着我们不能简单地做var bind = Function.bind
并打电话bind
作为一个独立的功能。
let log = () => console.log('Hello, World!')
let bind = Function.bind;
bind(log) // => Uncaught TypeError: Bind must be called on a function
______
创建独立函数bind
您共享的代码创建了一个简写(独立)函数,相当于Function#bind
但接受要绑定的函数作为其第一个参数以及将该函数绑定到的上下文作为其第二个参数,而不是调用bind
方法作为被绑定函数的成员(例如fn.bind(ctx)
).
// Create standalone `bind` function
let bind = Function.call.bind(Function.bind);
let obj = { hello: 'World!' }
let log = () => console.log(this)
let boundFn = bind(log, obj)
boundFn() // => { hello: 'World!' }
______
2.如何实现这个功能而不需要Function#bind
?
上述解决方案接受一个函数和第二个参数,该参数定义返回函数的上下文(this
)。我们可以使用辅助函数非常简单地模仿此功能,该函数接受相同类型的参数并返回一个函数,该函数在调用时使用给定的上下文和参数执行该函数Function#call
.
- 要绑定的函数
- 将函数绑定到的上下文
例如:
function bind (fn, ctx) {
return function (...args) {
fn.call(ctx, ...args);
};
}
请注意,这与创建绑定函数并不完全相同。你可以了解创建绑定函数期间发生的情况9.4.1.3 BoundFunctionCreate在规范中 https://www.ecma-international.org/ecma-262/6.0/#sec-boundfunctioncreate.