手动实现bind函数
bind函数语法
bind() 方法会创建一个新函数,当这个新函数被调用时,它的 this 值是传递给 bind() 的第一个参数, 它的参数是 bind() 的其他参数和其原本的参数。
语法:
fun.bind(thisArg[, arg1[, arg2[, ...]]])
thisArg 当绑定函数被调用时,该参数会作为原函数运行时的 this 指向。当使用 new 操作符调用绑定函数时,该参数无效。
arg1, arg2, … (可选)当绑定函数被调用时,这些参数加上绑定函数本身的参数会按照顺序作为原函数运行时的参数。
例如:
function fn(a, b, c) {
console.log(this);
}
var _fn = fn.bind({a:123});
fn(); // 输出:window
_fn(); // 输出:{a:123}
函数内的this指向
原理分析
1.bind函数是函数调用的,而js中函数可以视作对象,当bind作为对象方法时,函数内部this指向该对象本身,那么此时调用this就是调用这个函数对象
例如:
function fun() {
console.log("fun被调用");
}
function bind(obj) {
console.log("bind中的this:", this);
if (typeof this === "function") {
this();
}
}
bind(); // 输出:bind中的this: window
fun.bind = bind;
fun.bind(); // 输出:1.bind中的this: fun 2.fun被调用
2.对象方法的this指向该对象本身,所以在bind函数内部的this指向的函数,作为bind函数参数的对象方法即可
例如:
function bind(obj) {
if (typeof this === "function") {
obj.bindThis = this;
return () => {
obj.bindThis();
};
}
}
function testThis(obj) {
console.log("this:", this);
}
var a = { a: 123 };
testThis.bind = bind;
var fn = testThis.bind(a);
fn();// 输出:this: {a: 123}
testThis(); // 输出:this: Window
3.通过原型链,将bind函数作为Function构造函数的对象函数,因为所有函数都继承自Function函数所以所有函数都可以调用bind函数,而不需要手动赋值
function bind(obj) {
console.log("this:", this);
if (typeof this === "function") {
obj.bindThis = this;
return () => {
obj.bindThis();
};
}
}
function testThis(obj) {
console.log("this:", this);
}
// bind();
var a = { a: 123 }
// testThis.bind = bind;
Function.prototype.bind = bind;
var b = testThis.bind(a);
b(); // 输出:this: {a: 123}
缺陷(若有解决方案请在评论区传授一下)
1.原生的bind函数返回的函数不会改变内容,只是改变其this指向
原生:
本次实现: