详解bind函数

详解bind函数之前将 call 和 apply 的具体实现模拟写了一遍 今天就将 bind 函数的具体实现来写一遍看看 bind 一句话描述 将创建一个新函数 当这个函数被调用时 传入的第一个参数作为新的 this 对象 后续的参数作为绑定函数的参数与 call 和 apply 相同点 都可以传递参数不同点 apply 和 call 是会具体执行该回调函数 而 bind 是返回一个函数首先 我们实现一个简单的 bind 绑定 functionbind console log Mynameis this name v

function bindFoo(){ 
    console.log('My name is ' + this.name); } var bindObj = { 
   name : 'gui'} var foo = bindFoo.bind(bindObj); //改变this指向,并返回一个新的函数 foo(); //函数执行 输出My name is gui 
Function.prototype.bindFunc = function (context){ 
    var _self = this; //_self指向bindFoo函数 //_self = function bindFoo(){ console.log('My name is ' + this.name); } return function(){ 
    // 通过apply来改变this对象 _self.apply(context); } } 

第二步,我们要和call,apply一致考虑参数的情况

function bindFoo(age, height, weight){ 
    console.log('My name is ' + this.name + '。age is ' + age + '。height is ' + height + '。weight is ' + weight); } var bindObj = { 
   name : 'gui'}; Function.prototype.bindFunc= function(context){ 
    var _self = this; //重点1,先获取从第一个arguments,进行分割,var foo = bindFoo.bind(bindObj, '18')中因为传入的第一个是对象。所以获取从第二个到最后一个的参数 var args = Array.prototype.slice.call(arguments, 1); return function(){ 
    //重点2,此处获取的arguments是第二次foo('175', '130')中传入的参数,所以不需要从第二个开始获取 //和call,apply类似,我们也通过arguments来处理 var args2 = Array.prototype.slice.call(arguments); var bindArgs = args.concat(args2); _self.apply(context,bindArgs); } } var foo = bindFoo.bindFunc(bindObj, '18'); //改变this指向,并返回一个新的函数 foo('175', '130'); //函数执行 输出My name is gui。age is 18。height is 175。weight is 130 
function bindFoo(age, height, weight){ 
    console.log('My name is ' + this.name + '。age is ' + age + '。height is ' + height + '。weight is ' + weight); } var bindObj = { 
   name : 'gui'} var name = 'sichao'; var foo = bindFoo.bind(bindObj, '18'); //改变this指向,并返回一个新的函数 var fooObj = new foo('175', '130'); // 输出My name is undefined。age is 18。height is 175。weight is 130 
Function.prototype.bindFunc = function(context){ 
    var _self = this; var args = Array.prototype.slice.call(arguments, 1); var bindFunc = function(){ 
    var args2 = Array.prototype.slice.call(arguments, 0); var bindArgs = args.concat(args2); /* 第二步: 当作为构造函数new foo('175', '130')时,this 指向实例,因为第一步中bindFunc.prototype = this.prototype, 所以结果为true,当结果为 true 的时候,this 指向实例。 当作为普通函数foo('175', '130')时,this 指向 window,bindFunc指向绑定函数, 此时结果为 false,当结果为 false 的时候,this 指向绑定的 context。*/ var bindThis = this instanceof bindFunc?this :context; _self.apply(bindThis, bindArgs); } //第一步:先将返回函数bindFunc的原型对象修改为绑定函数bindFoo的原型对象  //实例就可以继承绑定函数的原型中的值 bindFunc.prototype = _self.prototype; return bindFunc; } 
Function.prototype.bindFunc = function(context){ 
    var _self = this; var args = Array.prototype.slice.call(arguments, 1); var turnFunc = function(){ 
   }; var bindFunc = function(){ 
    var args2 = Array.prototype.slice.call(arguments, 0); var bindArgs = args.concat(args2); var bindThis = this instanceof bindFunc?this:context; _self.apply(bindThis, bindArgs); } turnFunc.prototype = _self.prototype; bindFunc.prototype = new turnFunc(); return bindFunc; } 

好了,最后的最后,我们再兼容一下绑定函数不正确的情况:

Function.prototype.bindFunc = function(context){ 
    if(typeof this != 'function'){ 
    console.log(typeof this); throw new Error("not function!"); } var _self = this; var args = Array.prototype.slice.call(arguments, 1); var turnFunc = function(){ 
   }; var bindFunc = function(){ 
    var args2 = Array.prototype.slice.call(arguments, 0); var bindArgs = args.concat(args2); var bindThis = this instanceof bindFunc?this:context; _self.apply(bindThis, bindArgs); } turnFunc.prototype = _self.prototype; bindFunc.prototype = new turnFunc(); return bindFunc; } 
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/230323.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月5日 下午3:01
下一篇 2026年3月5日 下午3:22


相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号