bind、call、apply 都是用来改变this指向,有所不同的是bind返回的是创建新函数,而不是和call、apply一样去执行调用原本的函数
bind函数的特点:
- 改变this指向
- 新函数的this是bind函数的第一个参数,其余参数则作为新函数的参数
- 改变this指向后,返回值没有变
- 在函数的原型上
实现bind函数:
- 返回一个新的函数
Function.prototype.myBind = functtion () {
// 返回新函数
return function () {
// 代码块
}
}
- 将函数的this指向为传进来的第一个参数,并且把剩余的参数保存并返回
let obj = {
name: 'Rose',
gender: 'female'
}
// bind函数
Function.prototype.myBind = function (context) {
// 将原来的this保存,保证返回值不变
const _this = this
// 将参数列表转化为数组,除去第一个参数
let args = Array.from(arguments).slice(1)
// 返回新函数
return function () {
// 利用apply将this指向context,参数进行拼接
_this.apply(context, args.concat(Array.from(arguments)))
}
}
// 声明一个函数
function fn(a, b, c) {
console.log('函数内部this指向:', this)
console.log('参数列表:', a, b, c)
}
let newFn = fn.myBind(obj, 1, 2)
newFn('myBind构造函数')
let obj = {
name: 'Rose',
gender: 'female'
}
// bind函数
Function.prototype.myBind = function (context) {
// 将原来的this保存,保证返回值不变
const _this = this
// 将参数列表转化为数组,除去第一个参数
let args = Array.from(arguments).slice(1)
// 返回新函数
let fn = function () {
// 如果被new调用,this应该是fn的实例
return _this.apply(
this instanceof fn ? this : context || window,
args.concat(Array.from(arguments))
)
}
// 维护fn的原型
let temp = function () {}
temp.prototype = _this.prototype
// new的过程继承temp原型
fn.prototype = new temp()
return fn
}
// 声明一个函数
function fn(a, b, c) {
console.log('函数内部this指向:', this)
console.log('参数列表:', a, b, c)
}
let newFn = fn.myBind(obj, 1, 2)
new newFn('myBind构造函数')