美文网首页
深入浅出this

深入浅出this

作者: zy懒人漫游 | 来源:发表于2018-02-09 06:48 被阅读0次

    What's this?

    由于运行期绑定的特性,JavaScript 中的 this 含义非常多,它可以是全局对象、当前对象或者任意对象,这完全取决于函数的调用方式
    随着函数使用场合的不同,this的值会发生变化。但是有一个总的原则,那就是this指的是,调用函数的那个对象

    作为函数调用

    在函数被直接调用时this绑定到全局对象。在浏览器中,window 就是该全局对象

    console.log(this);//window
    function fn1(){
        console.log(this);
    }
    fn1();//window   因为在fn的作用域里找不到,就会像上找,这样就会找到window
    

    还有,函数里this不是代表函数本身,这个很重要,很多新人都会犯这个错误,包括我之前也老是觉得,函数里的this,代表的就是这个函数,这是错误的,下面我们来看这个例子

    var a = 100
    function fn(){
      var a = 1
      console.log(this.a);
    }
    fn()//100
    

    很多新手一看就觉得,咦!怎么打印的不是1,而是全局下的a呢?因为在函数里找不到this,那么就会去外面找,上面说了,外面的this代表window,所以console.log(this.a);实际上就是console.log(window.a);,所以打印出的值是100。

    内部函数

    函数嵌套产生的内部函数的this不是其父函数,仍然是全局变量

    function parent(){
      function children(){
        console.log(this);
      }
      children()
    }
    parent()//window
    

    首先会再函数内部找this,发现子函数里找不到this,那就去父函数找,还是找不到,最后就去父函数的外面也就是全局下找this,所以打印出的是window

    setTimeout、setInterval

    这两个方法执行的函数this也是全局对象

    document.addEventListener('click', function(e){
        console.log(this);
        setTimeout(function(){
            console.log(this);
        }, 200);
    }, false);
    

    第一个this是绑定事件的这个元素,第二个this代表的全局对象window,如下图所示


    image.png

    如果在函数里申明了var self=this,那么第二个this就变掉了,相当于把第一个this代表的元素保存起来了,我们直接来看代码。如果看的有点绕的话,可以这么想,我可以不用_this,可以用me、self来代替,效果一样

    image.png
    document.addEventListener('click', function(e){
        console.log(this);
        var me = this
        setTimeout(function(){
            console.log(me);
        }, 200);
    }, false)
    

    作为构造函数调用

    所谓构造函数,就是通过这个函数生成一个新对象(object)。这时,this就指这个新对象

    new 运算符接受一个函数 F 及其参数:new F(arguments...)。这一过程分为三步:

    • 创建类的实例。这步是把一个空的对象的 __proto__ 属性设置为 F.prototype 。
    • 初始化实例。函数 F 被传入参数并调用,关键字 this 被设定为该实例。
    • 返回实例。
    function Person(name){
        this.name = name;
    }
    Person.prototype.printName = function(){
        console.log(this.name);
    };
    
    var p1 = new Person('Byron');
    var p2 = new Person('Casper');
    var p3 = new Person('Vincent');
    
    p1.printName();
    p2.printName();
    p3.printName();
    
    p1.printName();这句话执行的时候,先执行p1 = new Person('Byron'),然后在new的时候,做了三件事,
    1、创建新的空对象
    2、然后是把这个空的对象的 __proto__ 属性设置为 Person.prototype 
    3、执行函数Person,遇到this,就认为this是刚才创建的对象,给它添加一个属性name,而这个属性的值就是函数Person的name
    执行完成之后,把新对象return出来赋值给p1
    这样就可以通过p1的方式去用了
    

    作为对象方法调用

    在 JavaScript 中,函数也是对象,因此函数可以作为一个对象的属性,此时该函数被称为该对象的方法,在使用这种调用方式时,this 被自然绑定到该对象,简单的来说,就是谁调用这个函数,这个函数指的就是谁(这个this就代表谁)。

    如:Object1.fn(),this指的就是Object1,
    假如:Object1.Object2.Object3.fn(),this指的就是Object3,
    this指向最后一次调用者

    var obj1 = {
        name: 'Byron',
        fn : function(){
            console.log(this);
        }
    };
    obj1.fn();//{name: "Byron", fn: ƒ}
    
    var fn2 = obj1.fn;
    fn2();//window 因为fn是全局变量,等同于执行winow.fn2()
    

    相关文章

      网友评论

          本文标题:深入浅出this

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