vue bind
vue的固定作用域:在methds里,vue使this指向始终指向了vue实例。
思路:
- 1.判断是否支持bind
- 2.兼容写法里传入函数fn和对象ctx
- 3.返回一个新函数,调用函数时使用call方法直接绑定函数作用域为ctx(为什么要返回一个新函数?bind不是立即执行的,需要调用才能执行)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
function polyfillBind(fn, ctx) { function boundFn(a) { var l = arguments.length return l ? ( l > 1 ? fn.apply(ctx, arguments) : fn.call(ctx, a) ) : fn.call(ctx) } boundFn._length = fn.length return boundFn }
function nativeBind(fn, ctx) { return fn.bind(fn, ctx) }
var bind = Funtion.prototype.bind ? nativeBind : polyfillBind
|
思路:
- 保存一份原函数
- 拷贝原函数原型给新函数原型
- 返回新函数
- 4.判断是否是新函数的实例
- 5.绑定this,执行结果
手写bind
bind的手写实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| Function.prototype.mybind = function (oThis) { const thisFn = this let args = Array.prototype.slice.call(arguments, 1) function boundFn () { const ctx = this instanceof boundFn ? this : Object(oThis) return thisFn.call(ctx, args.concat(Array.prototype.slice.call(arguments))) } boundFn.prototype = Object.create(thisFn.prototype) return boundFn }
|
函数柯里化
再来理解一遍:把接受多个参数的函数变换成接受一个单一参数的函数,并且返回接受余下参数而且返回结果的新函数的技术
1 2 3
| function add (x, y) { return x + y }
|
1 2 3 4 5
| function addc (x) { return function (y) { return x + y } }
|
就是说只让函数每次接收一个参数,余下的参数由返回的新函数去接收.
在很多情况下,我们都不会一次只传递一个参数,于是有了通用curry:
- 定长参数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| function curry(fn) { let len = fn.length; let preArgs = Array.prototype.slice.call(arguments, 1); return function () { const restArgs = Array.prototype.slice.call(arguments) const args = [...restArgs, ...preArgs] if (args.length >= len) { return fn.apply(this, args); } else { return curry.call(null, fn, ...args); } } }
|
- 不定长参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| function curry(fn) { let preArgs = [].slice.call(arguments, 1); function curried () { let restArgs = [].slice.call(arguments) let args = [...preArgs, ...restArgs] return curry.call(null, fn, ...args) } curried.toString = function () { return fn.apply(null, preArgs) } return curried; } function dynamicAdd() { return [...arguments].reduce((pre, cur) => { return pre + cur }, 0) } var add = curry(dynamicAdd) add(1)(2)(3)(4) add(1,2)(3,4)(5,6)
|