美文网首页Web前端之路让前端飞程序员
JavaScript学习笔记 (3) this详解

JavaScript学习笔记 (3) this详解

作者: 机智的马里奥 | 来源:发表于2017-03-05 23:40 被阅读122次

    概览

    this关键字在Javascript中的表现和其他语言略有不同。在严格模式和非严格模式下同样存在区别。在大部分情形下,this的值由函数的调用方式所决定。

    全局上下文

    全局环境中,this指代全局对象,无论是否在严格模式。

     console.log(this===window);//true
     
     this.a=37;
     console.log(window.a);//37
    

    函数上下文

    • 非严格模式下:
     function f1(){
      return this;
     }
     
     f1()===window; //true
    
    • 严格模式下:
     function f2(){
      "use strict";
      return this;
     }
     
     f2()===undefined;//true
    

    在普通函数调用中,非严格模式下,并且没有用****call****或者****apply****指定****this****的值,那么****this****默认设置为全局变量;在严格模式下,****this****的值等于它进入执行作用域时被设定的值****.****在上例中****this****没有被赋予任何值,所以它等于默认值****undefined****

    对象方法中的this

    当以对象里的方法的方式调用函数时,它们的this是调用该函数的对象。

    var object={
      value:10,
      getValue:function(){
        return this.value;
      }
    };
    
    console.log(object.getValue()); // 输出10
    

    构造函数中的this

    当一个函数被作为一个构造函数来使用(使用new关键字),它的this与即将被创建的新对象绑定。

     var Person=function(){
      this.age=20;
     }
     
     var mario=new Person();
     console.log(mario.age); //输出20
    

    call 和 apply

    call 和 apply是为了动态改变this而出现的,当一个Object没有某个方法,但是其他的有,则可以借助call或apply用其他对象的方法来操作。

     function printInfo(gender,age){
      alert(this.name+" is a "+gender+" and "+age+" years old ");
     }
     
     var person={
      name:"mario"
     };
     
     printInfo.call(person,"man","20");//mario is a man and 20 years old.
     printInfo.apply(person,["man","20"]);//mario is a man and 20 years old.
    

    call和apply的区别

    foo.call(this,arg1,arg2,arg3)==foo.apply(this,[arg1,arg2,arg3])==this.foo(arg1,arg2,arg3)
    //this是想指定的上下文
    

    ****JS****中,某个函数的参数数量是不固定的。所以当参数明确知道数量时,用****call****,而不确定的时候,用****apply****,然后将参数****push****进数组,当参数数量不确定时,函数内部也可以通过****arguments****这个数组来遍历所有的参数。

    bind方法

    ES5中引入了Function.prototype.bind. 调用f.bind(someObject)会创建一个与f具有相同函数体和作用域的函数,但是在这个新函数中,this将永久的被绑定到了bind的第一个参数,无论这个函数时如何被调用的。

     function origin(){
      return this.value;
     }
     
     var bind=origin.bind({value:"abcd"});
     console.log(bind());// "abcd"
     
     var object={value:100, origin:origin,bind: bind}
     console.log(object.origin(),object.bind()); //100,"abcd"
    

    上面这段代码首先声明了一个原有函数origin,然后用origin函数创建了一个与origin具有相同函数体和作用域的函数bind,在bind函数中,this被永久的绑定到了第一个参数也就是"abcd",所以在最后我们创建一个新的同时带有origin和bind函数的实例object后,origin函数中的this指代的是object本身,所以能输出object本身的value值100,但bind中的this已经无法改变,this.value将永远等于"abcd".

    DOM中的this

    当函数被用作事件处理函数时,它的this指向触发事件的元素。(这一点和前面对象方法中的this相似)

    假设我们有一个id为"test"的按钮:

     var button=document.getElementById("test");
     button.setEventListener("click",function(){
      alert(this.id);  //输出了按钮的id:test
     });
    

    由此可见这里this指向的就是触发click事件的元素--id为“test”的按钮。

    总结

    综上所述,this出现的场景可以被分为四类:

    • 有对象就指向调用对象(无论是对象方法中还是DOM中)
    • 没调用对象就指向全局对象
    • 用new构造的就指向被创建的新对象
    • 通过apply或call或bind可以改变this的指向

    参考

    相关文章

      网友评论

        本文标题:JavaScript学习笔记 (3) this详解

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