重学前端:原生实现 call、apply、bind 函数。

目录

  • 这三个函数的 特点
  • call & apply & bind第一个参数,到底传的什么
  • 这三个函数实际解决的是什么问题?

先看看怎么调用

let obj = {
	arr: [1, 6, 3, 5],
	getArr: function() {
		console.log(
			this.arr
		)
	}
}


// 1.call
Math.max.call(this, ...obj.arr)  // output 6

// 2.apply
Math.max.apply(this, obj.arr)     // output 6

// 3.bind
let getArr = obj.getArr;
getArr()    // undefined
getArr =  getArr.bind(obj)
getArr()    // [1, 6, 3, 5]

特点

  1. call
    第一个参数是当前上下文,而call 函数的实参 是只能一个一个传入的。
  2. apply
    第一个参数为当前上下文,而apply函数 是可以直接传入数组的
  3. bind
    将上下文绑定到传入的参数。

实现

call

Function.prototype.mycall = function(context ) {
	if (typeof this != 'function') {
        throw new TypeError('this is not a function')
    }
	// 位置1
    context = context || window
    // 位置2
    context.fn = this
    let arg = [...arguments].slice(1);
    let res = context.fn(...arg)
    delete context.fn
    return res
}
  1. call apply bind第一个传入的都是当前上下文
  2. 位置1:将上下文传入, 如果传入 null则指向window
  3. 位置2:当我们调用 mycall函数时,this指向 .(点)前的函数,然后赋值给 context
  4. 然后通过 arguments拿去传入参数
  5. 调用 记得用完删掉就行。

apply

实现思路和 call函数一样,只是参数 一个是单个,一个是数组。

Function.prototype.myapply = function(context) {
    if (typeof this != 'function') {
        throw new TypeError('this is not a function')
    }
    context = context || window
    context.fn = this
    let result
    if (arguments[1]) {
       result = context.fn(...arguments[1])
    } else {
        result = context.fn()
    }
    delete context.fn
    return result
}

bind

最重要的一点 就是 将上下文 指向传入的参数中

Function.prototype.mybind = function(context) {
    if (typeof this != 'function') {
        throw new TypeError('this is not a func')
    }
    let _this = this
    let arg = [...arguments].slice(1)
    return function F() {
        return _this.apply(context, arg.concat(...arguments))
    }
}

var person = {
    name: 'Gavin',
    getName() {
        console.log(this.name)
        return this.name
    }
}
person.getName() // Gavin


var getName = person.getName
getName()  // undefined
var Gavin = getName.mybind(person)

console.log(Gavin())  // Gavin
  1. _this指向 .前的 getName函数
  2. 然后 用 apply函数 将 getName函数的上下文指向person(即 context)

实际解决的问题

就是当 当前上下文this指向不是我们想要的时, 就可以使用这三个函数 将 this指向我们想要的结果

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章