call

call和apply就是为了改变某个函数运行时的上下文(context)而存在的,换句话说,就是为了改变函数体内部 this 的指向。

function a(name) {
            console.log(name, 111)
            console.log(this, 222)
        }
a('fanfei')

call,apply,bind_JS
使用call改变this

  function a(name) {
            console.log(name, 111)
            console.log(this, 222)
        }
       
        a.call({
            y: 100
        }, 'aaa')

call,apply,bind_call_02

上面只是举了一个简单的例子,现在换个复杂的

   function fruits() {}

        fruits.prototype = {
            color: "red",
            say: function() {
                console.log("My color is " + this.color);
            }
        }

        var apple = new fruits;
        apple.say();
         let banner = {
            color: "yellow"
        }
        apple.say.call(banner)

call,apply,bind_bind_03
使用call,这样就不需要重新定义say方法。
call的参数就是继续往后添加,对应就是函数的参数。
原函数有N个参数,那么call里面就要添加N+1个参数

function func(a,b,c)
{
    
}
func.call({},'a','b','c')

从第二个参数开始就是和原函数的参数一一对应

apply

apply和call的区别就是在参数问题上,call的第二个参数就是一个对象(无特殊要求),但是apply的第二个参数必须是数组,数组中的数值会被当做为函数中的参数

  function func(a, b) {
            console.log(a, 'aaa')
            console.log(b, 'bbb')
            console.log(this, 'this')
        }
        func.apply({
            name: 'fanfei'
        }, ['AAA', 'BBB'])

call,apply,bind_JS_04
原函数有N个参数,那么call里面就要添加2个参数

bind

bind和call很相似,第一个参数是this的指向,从第二个参数开始是接收的参数列表。区别在于bind方法返回值是函数以及bind接收的参数列表的使用。

bind返回值是函数
var obj = {
    name: 'Dot'
}

function printName() {
    console.log(this.name)
}

var dot = printName.bind(obj)
console.log(dot) // function () { … }
dot()  // Dot

call,apply,bind_数组_05
bind 方法不会立即执行,而是返回一个改变了上下文 this 后的函数。而原函数 printName 中的 this 并没有被改变,依旧指向全局对象 window。

call、apply和bind函数存在的区别:

bind返回对应函数, 便于稍后调用; apply, call则是立即调用。

除此外, 在 ES6 的箭头函数下, call 和 apply 将失效
call和apply 的区别就是在参数问题上的区别