函数的四种调用方式以及this指向

在ES6之前,我们要看一个函数内部的this到底是指向谁,那么就要通过观察函数是如何调用的,下面是函数的四种调用方式:

  1. 函数调用

示例1:

    var age=18;
    var p={
        age:15
        say:function(){
            console.log(this.age);//window.age:18
        }
    }
    var s1=p.say
    s1();       //函数调用

由示例1可以知道函数调用方式的时候this是指向window。

  1. 方法调用

示例2:

    var age=18;
    var p={
        age:15
        say:function(){
            console.log(this.age);//this:p
            //this.age->p.age:15
        }
    }
    p.say()//方法调用

示例2就是方法调用的实例,也就是对象调用了他自身的方法。最后,可以知道say函数里面的this指向是p对象。

  1. 构造函数的调用

示例3:

    var age=18;
    var p={
        age:15
        say:function(){
            //this:say构造函数的实例,实例中并没有age属性,值为:undefined
            console.log(this.age);
        }
    }
    new p.say()//构造函数调用
    //相当于:
    var s1=p.say;
    new s1();

示例3剖析:首先知道p是一个对象,他里面有say方法,那么此时有一个new关键字后面有一个函数调用,那么也就是说通过了new来调用一个函数,此时这个函数就可以说是构造函数咯!那么这个函数调用的方式就叫做构造函数调用咯!那么问题来了,此时函数内部的this是指向谁呢?示例3中的say函数内部的this是指向谁呢?输出打印结果可以知道this.age值为undefined,也就是并没有找到age的值。因为使用这个调用方式的函数内部的this就是该构造函数的实例。可是该构造函数的实例上并没有找到age属性,所以输出结果就是undefined。

  1. 上下文调用

实例4:

 //上下文调用方式,有3种,call、apply、bind
    function f1(){
        console.log(this);
    }
    //call方法的第一个参数决定了函数内部的this的值
    f1.call([1,3,5])
    f1.call({age:20,height:1000})
    f1.call(1)      
    f1.call("abc")
    f1.call(true);
    f1.call(null)
    f1.call(undefined);

    //上述代码可以用apply完全替换

实例4可以简单的这么理解:也就是call和apply方法里面的第一个参数决定了函数里面的this指向!

知道了call和apply方法调用,那么bind方法调用又是怎么样的?他们的区别是什么?
示例5:

 //bind基本用法
    function speed(){
        console.log(this.seconds);
    }
 //执行了bind方法之后,产生了一个新函数,这个新函数里面的逻辑和原来还是一样的,唯一的不同是this指向{ seconds:100 }
    var speedBind = speed.bind({ seconds:100 });
    speedBind();    //100

    (function eat(){
        console.log(this.seconds);
    }).bind({ seconds:360 })()  //360


由示例5可以看出来,bind方法可以改变一个函数的this指向,这个和call以及apply是一样的,但是不同的区别是,通过增加bind()方法来调用一个函数时,此时会生成一个新的函数,这个新函数和原来的旧函数里面逻辑是一样的,只不过此时旧函数里面的this指向就会变成了指向bind方法括号中的参数对象了。

你可能感兴趣的:(漫谈JavaScript)