少废话,show my codegit
原理都在注释里了github
// 不覆盖原生call方法,起个别名叫myCall,接收this上下文context和参数params Function.prototype.myCall = function (context, ...params) { // context必须是个对象而且不能为null,默认为window const _this = typeof context === "object" ? context || window : window; // 为了不和原有属性冲突,定义一个Symbol类型的属性 const key = Symbol(); // call方法的目的是改变函数的this指向,函数的this指向它的调用者,也就是说咱们的目标是改变函数的调用者。 // 下面的this就是函数自己,给_this增长一个名为[key]的方法指向this,就能用_this来调用this了 _this[key] = this; const result = _this[key](...params); // 获取函数执行结果后,删除以上添加的属性 delete _this[key]; return result; };
和call的区别在于第二个参数app
Function.prototype.myApply = function (context, params) { return this.myCall(context, ...params); };
和call的区别在于不当即执行,返回一个函数便可函数
Function.prototype.myBind = function (context, ...params) { const _this = this; // 返回的函数也能接收参数,可是是放在params后面 return function (...args) { return _this.myCall(context, ...[...params, ...args]); }; };
函数柯里化,举例,有以下函数this
function test(a, b, c, d, e) { console.log(a + b + c + d + e); }
有一个curry转换函数对test函数进行一些转换prototype
function curry(){ // todo } const transformTest = curry(test, ...args)
转换以后,本来一次性传过去的参数如今能够分步传参code
// 使得 test(1,2,3,4,5) // 等同于 transformTest(1)(2)(3)(4)(5) // 或者 transformTest(1, 2)(3)(4, 5) // 又或者 transformTest(1, 2, 3, 4)(5)
curry函数应该怎么写?orm
function curry(fn, ...args) { // 判断参数个数是否是等于原函数参数个数 // 若是是,直接返回调用结果 if ([...args].length >= fn.length) { return fn(...args); } else { // 若是不是,则返回一个函数 return (...params) => { // 将前面传的所有参数传给curry,回到第一步的if判断,直到参数个数知足要求 return curry(fn, ...args, ...params); }; } }
本文GitHub连接:手写系列:call、apply、bind、函数柯里化对象