apple,call和bind的理解

apply call 和 bind 函数的理解

提供自己手动绑定this的方法

函数的调用

首先在js里函数调用有4种模式:方法调用、正常函数调用、构造器函数调用、apply/call 调用。同时,无论哪种函数调用除了你声明时定义的形参外,还会自动添加2个形参,分别是 this 和 arguments。

this的自动绑定

  1. 方法调用 this 绑定的就是对象本身
  2. 如果你在一个函数前面带上 new 关键字来调用,那么 js 会创建一个 prototype 属性是此函数的一个新对象,同时在调用这个函数的时候,把 this 绑定到这个新对象上。当然 new 关键字也会改变 return 语句的行为
  3. 函数的正常调用,也是会默认指定this。 通常是windows

this的手动绑定

在js里,我们编写的函数,也是属于对象, 由系统定义好的Function函数来创建出来的。所以函数都会有一个共有的原型对象,Fuction.prototype.而这个原型自带有好几个属性和方法,其中就有这里困惑的 bind、call、apply方法。
而三个函数有一个共同的特点就是可以设置this的值。上面的3种函数调用方式,你可以看到,this都是自动绑定的,没办法由你来设,当你想设的时候,就可以用他们了

apply

它让我们构造一个参数数组(函数运行所需的参数)传递给函数,同时可以自己来设置 this 的值,这就是它最强大的地方,。apply 函数接收 2 个参数,第一个是传递给这个函数用来绑定 this 的值,第二个是一个参数数组。

call

它允许我们传入不定长参数(函数运行所需的参数),同时可以自己来设置 this 的值。 只是参数和apply不一样。

bind

bind() 函数,上面讲的无论是 call() 也好, apply() 也好,都是立马就调用了对应的函数,而 bind() 不会, bind() 会生成一个新的函数,bind() 函数的参数跟 call() 一致,第一个参数也是绑定 this 的值,后面接受传递给函数的不定参数。 bind() 生成的新函数返回后,你想什么时候调就什么时候调

用法

apply 和 call

这两个方法的用途都是在特定的作用域中调用函数,实际上等于函数体内this对象的值, 他们会立即执行

  1. 作用在方法上的理解
    当对象o上不存在方法f时,我们通过call去指定 this时,就相当于在o上新增一个f方法,然后调用完成之后删除。
    f.call(o); f.apply(o); // 假设o中不存在m方法,则等价于: o.m = f; //将f存储为o的临时方法 o.m(); //调用它,不传入参数 delete o.m; //将临时方法删除

    实例:

    window.color = "red";
    var o = {color: "blue"};
    function sayColor(){
        console.log(this.color); // 打印调用对象的颜色值
    }
    sayColor();   // 打印 全局对象window 的color值
    sayColor.call(window);  // 打印 全局对象window 的color值
    sayColor.call(this);// 打印 全局对象window 的color值
    sayColor.call(o); // 打印 o 对象的 color值
    console.log(o);
    // sayColor.call(o)等价于:
    // o.sayColor = sayColor;
    // o.sayColor();   //blue
    // delete o.sayColor;
  1. 作用于类上的理解
    a对象的方法应用到b对象上(函数apply的意思正好说明符合这样理解:a对象应用到b对象上去)
    a对象既然添加到b对象上了。那么b对象自然就拥有了a对象所有的内容。所以,b对象就继承了a对象了。 和C++的继承有点相似
        function class1(){
            this.name = function(x){
                alert("我是class1的name(x)方法"+",我是class1name函数的参数(" + x + ")");
            }
        }

        function class2(){
            class1.call(this); // this 就是class的对象
        }

        var c1 = new class2();
        //c1.name(20);
        console.log(c1); // 
        class2();
  1. 看参数的不同使用
    function sum(num1, num2){
        console.log("num1:" + num1 + "  num2:" + num2);
        return num1 + num2;
    }
    function applySum1(num1, num2){
        return sum.apply(this,arguments); 
    }
    function applySum2(num1, num2){
        return sum.apply(this,[num1,num2]);
    }
    function callSum(num1, num2){
        return sum.call(this,num1,num2);
    }
    console.log(callSum(1,2));

bind

bind() 函数,上面讲的无论是 call() 也好, apply() 也好,都是立马就调用了对应的函数,而 bind() 不会, bind() 会生成一个新的函数,bind() 函数的参数跟 call() 一致,第一个参数也是绑定 this 的值,后面接受传递给函数的不定参数。 bind() 生成的新函数返回后,你想什么时候调就什么时候调

var m = {
            "x" : 1
    }
function foo(y){
    console.log(this.x + y);
}
foo.apply(m, [5]); // apply 接收数组 会自动展开
foo.call(m,5);  // call 接受可变参数
var foo1 = foo.bind(m);
foo1(5);

总结

其实这里的this改变你可以认为,是给对象添加了一个方法,之后删除。可能这样好理解点。而对于参数而言,其实就是一个要求数组,两个要是不定长参数,视情况用,还有就是bind返回的是一个新函数,不会立即执行。

apple,call和bind的理解

上一篇:移动端利用chrome浏览器在PC端进行调试方法


下一篇:vue----webpack模板----axios请求