你不知道的JavaScript笔记之关于this

关于this

this 关键字在JavaScript中也算是相当复杂的了,它被定义在所有的函数的作用于中。
之前用this总是模棱两可,能用对,但是有时候真正解释的时候,说着说着自己都被绕迷糊了。请各路大神给以指点,有出入的地方给以纠正~

为什么要用this

我们在知道怎么做之前,我们需要先明白为什么
不要老是看别人用的this怎么用的,要先明白别人为什么要用它!!

首先看一段用this的代码,然后分析为什么用它:

           function transform(){
               return this.name.toUpperCase();
           }

           function statement(){
           var myState = "Hello, I'm  "+transform.call(this);
           console.log(myState);
           }

         var me = {
             name:"Pakar"
         };

         var you = {
             name:"Lucy"
         };

         transform.call(me);//PAKAR
         transform.call(you);//LUCY

         statement.call(me);//Hello,I'm PAKAR
         statement.call(you);//Hello,I'm LUCY

这段代码使用this来实现的,下面我们不使用this,通过给它传递参数(一个上下文对象)来实现一下:

         function transform(context){
               return context.name.toUpperCase();
           }

           function statement(context){
           var myState = "Hello, I'm  "+transform(context);
           console.log(myState);
           }
         var me = {
             name:"Pakar"
         };

         var you = {
             name:"Lucy"
         };

         transform(me);//PAKAR
         transform(you);//LUCY

         statement(me);//Hello,I'm PAKAR
         statement(you);//Hello,I'm LUCY*/

通过上面两端代码的对比,想必你也发现了,在不使用this的情况下,我们显式的传递了一个context。然而,使用this这样隐式的传递一个对象的引用,是不是很简洁又容易复用呀~

再补一个例子

          //为对象中的方法指定一个 this
        var obj = {
          name: 'Pakar',
          foo: function () {
            console.log(this);
          }
        }

        var obj2 = {
          name: 'Lucy'
        };

        obj.foo.call(obj2);// Object {name: "Lucy"}

显式传递:

        var obj = {
          name: 'Pakar',
          foo: function (context) {
            console.log(context);
          }
        }

        var obj2 = {
          name: 'Lucy'
        };

        obj.foo(obj2);

如果你一直用显式的方式传递的话,你会发现代码越来越混乱,使用this就好多啦。同时也能够自动引用。

this的误解

有时候我们太在意这个单词的字面意思,就会造成一些误解。
一般有两种错误的误解:
* 指向自身
* this指向函数的作用域(有点复杂,有些情况正确,其他情况却是错误)

这是两个很常见的误解

指向自身

先看一个例子:

       function foo(num){
         console.log("foo: "+num);
         this.count++;
          }

          foo.count = 0;

          var i;

          for(i=0;i<10;i++){
          if(i>5){
              foo(i);
          }
          }
       /*
         foo: 6
         foo: 7
         foo: 8
         foo: 9
       */

        //window   i foo 
        //foo    num 当执行到foo.count=0时候,向函数对象添加一个属性count
          console.log(foo.count); //0
          console.log(count);//NaN

这里我们会发现foo{…}执行了4次,foo.count仍然是0,要是还说this是指向自身的话,应该就是错误了吧,这就是this的误解之一,并不是都指向自身。

分析代码:
执行到foo.count=0时候,向函数对象添加一个属性count。函数内部的this.count并不是指向那个函数的this。那这个函数里面的count是哪个count呢?我们在window下面输出的值是NaN,可以看出,这个count是全局变量count。这是怎么造成的呢?

这造成的真正原因就是JS词法作用域

词法作用域,也可以说代码作用域,代码在编写时候体现出来的作用范围,代码一写好,你不用执行,作用范围就已经确定好了,这就是词法作用域
整个代码只有函数可以限定作用域

所以在foo函数里面,并没有count,所以就会像它的父级函数找,在非严格模式下window会声明这个count,这个时候count为undefined,所以++会返回NaN;

this的作用域

有时候误解this指向函数的作用域,某种情况下它正确,其他情况却错误。
this在任何情况下都不指向函数的词法作用域。作用域和对象确实挺像。

     function foo(){
             var a = 2;
             this.bar();
         }
         function bar(){
             console.log(this.a);//undefined
         }
         foo();

这里想用this来引用函数的词法作用域,想引用foo的词法作用域,然后在bar里面操作foo作用域里面的a。刚才也说了this不指向函数的词法作用域,所以this也不可能在词法作用域中找到什么。

总结:
学习this首先要明白this既不指向函数自身也不指向函数的词法作用域。它在运行时进行绑定,不要想着在编写时,当然它的绑定和函数声明位置没什么关系!

this在函数被调用时发生绑定,它指向什么完全取决于函数在哪里被调用。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值