bind 位于 Function.prototype 上,我们来做一个polyfill,边测试变完成手写 bind。
新建目录bind,在其中创建src/index.js和test/index.js。之后操作都在bind目录中进行。
fn.bind(asThis)
- 为了获取测试环境,以下代码以
bind2作为手写的bind进行测试。 - 一个函数
fn1调用bind方法,这个函数fn1就是bind中的this fn1调用bind方法时传入第一个参数{name: 'lk'},返回一个函数fn2fn2调用时将这个参数{name: 'lk'}作为this调用fn1,返回结果- 测试用例test/index.js中,函数
fn1直接返回其this,应为调用bind时第一个参数{name: 'lk'},所以断言fn2().name === 'lk' - 执行
node test/index.js,无报错,测试通过
1 | // src/index.js |
1 | // test/index.js |
fn.bind(asThis, param1, param2)
- 完善上一步代码,除了传入第一个参数作为
this,同时传入其他参数。改写代码如下 - 执行
node test/index.js,无报错,测试通过
1 | // src/index.js |
1 | // test/index.js |
fn.bind(asThis, param1, param2)(p3, p4)
- 继续完善,
fn1在调用bind时所返回的函数fn2在被调用时也传入参数 - 改写代码如下
- 执行
node test/index.js,无报错,测试通过
1 | // src/index.js |
1 | // test/index.js |
支持 new 的 bind
使用 new 调用函数时实际进行了以下操作:
1 | new fn(a) |
原版的 bind 是支持 new 的
1 | //在浏览器控制台测试原版 bind |
改写我们的 bind 使其支持 new 调用:
1 | // src/index.js |
1 | // test/index.js |
使用旧的API
现在手写的 bind2 已经实现了原版 bind 的功能。因为是在做 polyfill,不应该用到所有跟 bind 同时出现的所有新的api,同时必须进行错误处理。使用旧的语法修改代码:
1 | // src/index.js |
完