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'}
,返回一个函数fn2
fn2
调用时将这个参数{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 |
完