this,call和apply

作者: 臭臭臭魁 | 来源:发表于2016-09-30 16:50 被阅读29次

    1:this

    跟大多数的语言一样,javascript的this总是指向一个对象,而具体指向哪个对象是在运行时基于函数的运行环境动态绑定的,而非被声明时的环境。

    2:this的指向

    除去不常用的evel和with的情况,this指向大概分为以下四种
    • 1:作为对象的方法调用,
    • 2:作为普通函数调用,
    • 3:构造器调用,
    • 4:Function.prototype.call或Function.prototype.apply调用

    2.1:作为对象的方法调用

    当函数作为对象的方法被调用时,this指向该对象;

    var obj = {  
          a: 1,    
          getA:function () {        
            alert(this === obj);//true
            alert(this.a)//a
          }
     };
    obj.getA();
    

    2.2:作为普通函数调用

    当函数不作为对象的属性调用时,用普通的函数调用时,此时的this总是指向全局对象。在浏览器里全局对象就是window;

    var name = "globalName";
    var getName = function () {
        return this.name;
    };
    console.log(getName());//输出:globalName
    //    或者:
    var myObject = {
        name:"jiankui",
        getName:function () { 
           return this.name;
        }    
    }; 
    var getName = myObject.getName ; 
     console.log(getName())//输出:globalName
    

    2.3:构造器调用

    除了一些内置的函数,大部分的javascript函数都可以当做构造器使用,构造器的外表跟普通的函数一模一样,区别在于调用的方式,当用new运算符调用函数时,改函数通常返回一个对象,构造器的this就指向这个返回的对象

    var myClass = function () {
        this.name= "jiankui";
    };
    var obj = new myClass();
    console.log(obj.name);//jiankui
    

    但是用new构造器时,还要注意一个问题,如果构造器显式的返回一个object类型的对象,那么此次运算结果最终会返回这个对象,而不是我们上面期待的this

    var myClass = function () {
      this.name= "jiankui";
      return {//显式的返回一个对象
          name: "jiankui2"
      }
    };
    var obj = new myClass();
    console.log(obj.name);//jiankui2
    

    如果构造器不显式的返回任何数据,或者是返回一个非对象类型的数据,就不会造成上述困扰

    var myClass = function () {
      this.name= "jiankui";
      return  "jiankui2";
    };
    var obj = new myClass();
    console.log(obj.name);//jiankui
    

    2.4:Function.prototype.call或Function.prototype.apply调用

    跟普通函数调用相比,用Function.prototype.call或Function.prototype.apply可以动态的改变传入函数的this

    var obj1 = {
    name:"jiankui",
    getName:function () {
        return this.name;
    }};
    var obj2 = {
        name:"jiankui2"
    };
    console.log(obj1.getName());//jiankui
    console.log(obj1.getName.call(obj2));//jiankui2
    

    3:丢失的this

    这是个经常遇到的问题,先看代码

    var obj = {
    name:"jiankui",
    getName:function () {
        return this.name;
    }};
    var getName2 =obj.getName;
    console.log(obj.getName());//jiankui
    console.log(getName2());//undefind
    

    当调用obj.getName()时,getName被当做对象的方法调用,根据2.1提到的,this指向obj对象,所以obj.getName()输出jiankui。
    当用另一个变量getName2()来引用obj.getName,并调用getName2()时,根据2.2提到的,此时是作为普通函数调用,this指向window,而我们的window没有定义,所以为undefined

    4 call和apply

    apply接收两个参数,第一个参数指定了函数体内this对象的指向,第二个参数为一个带下标的集合,可以为数组和类数组,apply方法把这个集合中的元素作为参数传入被调用的函数:

    var func = function (a, b, c) {
       console.log([a, b, c]);//[1,2,3]
    };
    //数组的三个值分别对应abc三个参数
    func.apply(null,[1,2,3]);
    

    call传入的参数数量不固定,跟apply相同的是,第一个参数也是代表函数体内的this指向,从第二个参数开始往后,每个参数被依次传入函数

    var func = function (a, b, c) {
       console.log([a, b, c]);//[1,2,3]
    };
    func.call(null,1,2,3);

    相关文章

      网友评论

        本文标题:this,call和apply

        本文链接:https://www.haomeiwen.com/subject/tqzlyttx.html