关于this的一些观点和问题

相信很多前端开发工程师在学JavaScript的时候,都被this迷惑过,用起来是相当的爽,也是极易出错的。

今天就谈谈自己对于这些的理解。

this的一些概念及工作原理

    JavaScript 有一套完全不同于其它语言的对 this 的处理机制。它是一个在每个函数作用域中自动定义的特殊标识符关键字。若要了解this的原理,我们试着通过一些具体的例子来说明this的动机和用途。

function getThis() {
   console.log(this);
}
var obj = {
   this.name = 'zs',
   getThis:getThis
}

getThis(); //window
obj.getThis(); //obj

        通过上面的例子我们可以知道当this在函数里执行会出现不同的效果。这样我们就可以想到this只在调用的时候才会确定到底是指向谁。具体的指向对象,我并不想过多的去挖掘this的实现机制,我想通过更简洁的事件方法来阐述我的一些想法。

一、函数调用

        当函数在window的全局作用域内生命的,就确定了其所在的作用域,不管在什么地方使用只要是函数来调用的,这个this就指向了window。

function fn () {
   console.log(this);
}

var obj = {
  name: 'zs',
  func:function () {
      fn();
  }
}

fn(); // window
obj.func()  //window

        在上面的案例中我们看见了,函数声明之后,不管在什么地方使用,只要通过的是函数本身的调用,this都是指向window。

二、方法调用

        方法调用,顾名思义,就是对象调用函数。通过对象调用函数,这里的this就指向调用者。下面看下例子。

    var age = 38;
    var obj = {
      age: 18,
      getAge: function () {
        console.log(this.age);
     }
   }
  
   obj.getAge();   //18

        在这里我们看到就是这里的this指向的就是obj,所以得到的就是18。其实很好理解,这个函数在对象中赋值,也是在对象中调用的,可以很容易的得到this是指向这个对象的。

三、混合使用

    var age = 38;  //window.age
    var obj = {
      age:18,  //obj.age
      getAge:function () {
        console.log(this.age);//???
        function foo(){
          console.log(this.age);//????
        }
  
        //函数调用模式
        foo();
      }
    }
    //方法调用模式
    obj.getAge();    //18 38

        通过上面的例子我们可以看到,函数foo在对象函数内声明的,也在其中调用,得到的结果就是这个this指向的是window。

通过obj方法调用,这个函数执行的时候,这个this就指向当前调用的这个对象。

        所以可以稍微总结一下,当是函数调用时,这个this就指向window,当作为方法调用的时候,这个this就指向调用的对象。下面还有一个例子。

 var length = 10
  function fn() {
    console.log(this.length)
  }
  var obj = {
    length: 5,
    method: function (fn) {
      fn()
       //方法调用模式: this指向arguments自己
      arguments[0]();    //arguments.length 4
    }
  }

  obj.method(fn, "222", "333", "4444");  //10    4

        其实这里最容易出错的是这里的arguments其实是个对象,首先我们要弄清楚arguments是什么,它是函数传的实参都保存在这个数组内的。这样我们就可以将  arguments[0]( )  理解为 arguments.fn(),这样我们可以很明显的看到这是个方法调用,此时的this指向的就是arguments这个对象。第一个看结构就是函数调用,所以答案就是10和4。

四、构造函数中的this

        在构造函数使用时都会通过一个new,其实new在创建对象的时候干了四件事

1. 创建一个新的对象(类型取决了new后面跟的构造函数)
2. 让构造函数内部的this指向这个新的对象 
3. 执行这个构造函数
4. new会返回这个新创建的对象  

  

五、call 、apply、bind方法改变this。

      任何函数都有call 、apply、bind这三个方法。

         call、apply一般称为上下文调用模式,也叫方法借调。使用方法: 函数.call() 或者 函数.apply()

         call方法可以调用一个函数,并且可以指定这个函数的this指向。fn.call()调用的这个函数,此时函数的内部

的this是固定,固定为call的第一个参数。

         伪数组可以跟数组一样进行遍历,通过下标操作。

         常见的伪数组:arguments、document.getElementsByTagName的返回值、jQuery对象

         var arrayLike = {
                  0:"张三",
                  1:"李四",
                  2:"王五",
                  length:3

           }

        伪数组可以和数组一样进行遍历

        伪数组借用数组的方法

        Array.prototype.push.call(arrLike, "赵六");

        Array.prototype.join.call(arrLike, "-");

        将伪数组转换成真数组

        var arr = Array.prototype.slice.call(arrLike);

        apply方法

        apply()方法的作用和 call()方法类似,只有一个区别,就是apply()方法接受的是一个包含多个参数的数

。而call()方法接受的是若干个参数的列表

        call和apply的使用场景:

        如果参数比较少,使用call会更加简洁,参数存放在数组中,此时需要使用apply

        bind方法

        bind()方法创建一个新的函数, 可以绑定新的函数的this指向

        返回值:新的函数

        参数:新函数的this指向,当绑定了新函数的this指向后,无论使用何种调用模式,this都不会改变。

        var newFn = fn.bind(window);

           

        以上这些就是自己对于this在工作中的一些总结吧。基本上通过这些方法对

于this的判断还是比较准确的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值