实现一个bind函数
var fn = function(a, b, c, d) {
return a + b + c + d
}
fn.bind(scope, a, b)(c, d)
Function.prototype.bind = function(scope) {
let newFn = this
let args = Array.prototype.slice.call(arguments, 1)
let fbind = function() {
return newFn.apply(scope, args.concat(Array.prototype.slice.call(arguments)))
}
return fbind
}
调用方式
1.直接调用 (内部this指向全局,在浏览器下,指向window)
2.构造函数的调用,通过bind绑定的this无效
思考,下面函数执行时多少,this是什么
var fn = function(a,b) {
console.log(this)
console.log( a + b)
return a+b ;
}
fn.bind({name:1},1,2).call({name:2},3,4) // {name: 1} 3
//fn.bind({name:1},1,2) 返回xxx
function xxx() {
return fn.apply({name: 1},[1,2].concat(Array.prototype.slice.call(arguments)))
}
// xxx.call({name:2},3,4) 调用 xxx(绑定了xxx的this= {name:2})
// xxx里面通过apply调用已经制定了this的fn函数
fn.apply({name: 1},[1,2,3,4]) // this => {name: 1} a=1, b=2
所以当我们执行fn.bind({name:1},1,2).call({name:2},3,4) ,本质上call并不能改变bind的返回函数的this,只是改变了内部封装了一个函数(xxx)的this,这也是bind的this参数不能被重写的原因。
总结bind函数到底做了什么
fun.bind(thisArg[, arg1[, arg2[, ...]]])
// 简化版
Function.prototype.bind = function bind(self) {
return function() { return fn.apply(self) }
}
当一个函数(fn)使用函数原型链上面的bind函数的时候,传递this(thisArg)和参数进去,返回的是一个新函数(xxx),新函数内部调用的是通过apply调用原来的函数(fn)并制定原函数(fn)的this。用简单的代码表示就是:
function fn(a,b) {
return a+b;
}
fn.bind({name:1},1,3) 相当于变成这样=> function xxx() {
return fn.apply({name: 1},Array.prototype.slice.call(arguments));
}
箭头函数的this(定义时候的this)
一句话总结: 箭头函数的函数体内的this就是定义时候的this,和使用所在的this没有关系。
即:在定义箭头函数的时候就已经绑定了this,可以理解为就是在定义的时候,通过bind函数进行强行绑定this。