javascript bind 方法封装
Function.prototype.bind方法非常强大,可以绑定一个函数的上下文可以帮我们解决很多问题,有没有好奇这样强大的方法究竟在底层是怎么实现的呢?本文来告诉你
首先我们来看看bind方法的作用:
function func() {
console.log(this.a, Array.prototype.slice.call(arguments));
}
var a = 10;
var obj = {
a: 20
}
func(1);//10 [1]
var newfunc = func.bind(obj,1,2,3);
console.log(newfunc===func)//false
newfunc(4,5,6);//20 [1,2,3,4,5,6]
var obj1=new newfunc();//undefined [1,2,3]
obj1.a=30;
console.log(obj===obj1,obj1.a,obj.a)//false 30 20
根据上面的代码我们得出:
- bind方法执行后 返回一个全新的函数
- 函数newfunc执行时 实际上还是执行的func函数只的功能不过this变成了obj
- 函数newfunc执行时 传递的参数会 被拼接到 func.bind的参数后面 并传给func执行
- 当函数newfunc执行时 内部this不会改变仍然指向实例化对象
封装思路:
- 返回一个新的函数 新的函数里面实际上执行的还是原来的函数 只不过用apply方法改变了this的方向
- 用数组的concat方法吧内外参数列表连接起来,形成一个新的数组,给apply方法第二个参数
- 在返回的函数的prototype上加一个属性,如果函数内部的this找得到这个属性就说明是new执行的
所以有以下代码:
Function.prototype.myBind = function (ctx) {
var that = this,//预存this 即实际执行的那个函数 func.mybind()内部this指向func
slice = Array.prototype.slice;//预存数组分割方法
var outsideArg = slice.call(arguments, 1);//从第一位开始截取
fun.prototype.__mypro__=true;
function fun() {
//返回一个新的函数 实际上执行的还是外面的this即你调用bind方法的那个函数
var insideArg = slice.call(arguments, 0);//里面函数的参数
var contex=this.__mypro__?this:ctx;/*如果this找得到__mypro__说明是new执行无需改变this*/
return that.apply(contex,outsideArg.concat(insideArg)/*将内外参数连接起来*/);
};
return fun;
}
经过测试新封装的myBind方法跟原来的bind方法功能一致 myBind方法封装成功
网友评论