apply,call,bind用js原生实现(代码实例)
程序员文章站
2022-05-03 17:52:59
apply,call,bind用js原生实现(代码实例)
// apply第一个参数是函数的执行环境this,第二个参数是一个数组,这个数组会自动散开成为函数的参数
function.prot...
apply,call,bind用js原生实现(代码实例)
// apply第一个参数是函数的执行环境this,第二个参数是一个数组,这个数组会自动散开成为函数的参数 function.prototype.apply = function (x, y) { x = x || window y = y || [] x._apply = this // this为当前函数:使函数指向x if (!x._apply) { // 如果作用域x不可修改:则给它的原型添加函数 x.constructor.prototype._apply = this } var r , j = y.length switch (j) { case 0: r = x._apply(); break case 1: r = x._apply(y[0]); break case 2: r = x._apply(y[0], y[1]); break case 3: r = x._apply(y[0], y[1], y[2]); break case 4: r = x._apply(y[0], y[1], y[2], y[3]); break default: r = eval('x._apply(' + y.join() + ')'); break // eval执行效率底,所以先用js写常用的调用 } try { delete x._apply ? x._apply : x.constructor.prototype._apply // 删除为了修改函数作用域的临时指向 } catch (e) {} return r //返回函数执行的结果 } // call 第一个参数是函数的执行环境this,从第二个参数开始都是给函数的参数 function.prototype.call = function () { let len = arguments.length - 1, x = args[0], y = [] for (let i = 0; i < len; i++) { // 把arguments类数组对象转化为数组 可以简写为:[].slice.apply(arguments, 1) y[i] = arguments[i + 1] } return this.apply(x, y) } // bind 修改函数的执行环境,返回一个新函数,参数和call一样 function.prototype.bind = function () { // 形成一个闭包,返回一个行函数 let x = arguments[0], len = 0, y = [], i, j, fn = this for (i = 0, len = arguments.length - 1; i < len; i++) { y[i] = arguments[i + 1] } return function () { for (j = 0, len = arguments.length; j < len;) { y[y.length] = arguments[j++] } return fn.apply(x, y) } }