bind、call、apply

区别

call和apply

call和apply都是为了解决改变this的指向。作⽤都是相同的,只是传参的⽅式不同。
第⼀个参数是一个对象,除此之外, call可以接收⼀个参数列表,apply只接受⼀个数组参数

let a = {
 value: 1
}
function getValue(name, age) {
 console.log(name)
 console.log(age)
 console.log(this.value)
}
getValue.call(a, 'yck', '24')
getValue.apply(a, ['yck', '24'])

 

bind

bind 和其他两个⽅法作⽤也是⼀致的,只是该⽅法会返回⼀个函数。并且我们可以通过 bind 实现柯⾥化

 

实现

思路:如果不传⼊第⼀个参数,那么默认为window
三个方法改变了 this 指向,让新的对象可以执⾏该函数。那么思路是否可以变成给新的对象添加⼀个函数,然后在执⾏完以后删除?

.bind()

bind() 方法创建一个新的函数,在 bind() 被调用时,这个新函数的 this 被指定为 bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用。

const module = {
            x: 42,
            getX: function() {
                return this.x;
            }
        };

        const unboundGetX = module.getX;
        console.log(unboundGetX()); // The function gets invoked at the global scope
        // expected output: undefined

        const boundGetX = unboundGetX.bind(module);
        console.log(boundGetX());
        // expected output: 42

实现⼀个自己的bind函数

Function.prototype.myBind = function(context) {
            if (typeof this !== 'function') {
                throw new TypeError('Error')
            }
            var _this = this
            var args = [...arguments].slice(1)
                // 返回⼀个函数
            return function F() {
                // 因为返回了⼀个函数,我们可以 new F(),所以需要判断
                if (this instanceof F) {
                    return new _this(...args, ...arguments)
                }
                return _this.apply(context, args.concat(...arguments))
            }
        }

 

.call()

call() 方法使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数。

        function Product(name, price) {
            this.name = name;
            this.price = price;
        }

        function Food(name, price) {
            Product.call(this, name, price);
            this.category = 'foot';
        }

        console.log(new Food('cheese', 5).name);

  

实现⼀个自己的call函数

        Function.prototype.myCall = function(context) {
            var context = context || window
                // 给 context 添加⼀个属性
                // getValue.call(a, 'yck', '24') => a.fn = getValue
            context.fn = this
                // 将 context 后⾯的参数取出来
            var args = [...arguments].slice(1)
                // getValue.call(a, 'yck', '24') => a.fn('yck', '24')
            var result = context.fn(...args)
                // 删除 fn
            delete context.fn
            return result
        }

  

.apply()

apply() 方法调用一个具有给定this值的函数,以及以一个数组(或类数组对象)的形式提供的参数。

const numbers = [5, 6, 2, 3, 7];

const max = Math.max.apply(null, numbers);

console.log(max);
// expected output: 7

const min = Math.min.apply(null, numbers);

console.log(min);
// expected output: 2

  

实现一个自己的apply函数

Function.prototype.myApply = function(context) {
            var context = context || window
            context.fn = this
            var result
                // 需要判断是否存储第⼆个参数
                // 如果存在,就将第⼆个参数展开
            if (arguments[1]) {
                result = context.fn(...arguments[1])
            } else {
                result = context.fn()
            }
            delete context.fn
            return result
        }

  

 

  

 

posted on 2022-04-26 10:47  前端码牛  阅读(20)  评论(0编辑  收藏  举报

导航