正文 2402字数 81,460阅读

Java 语言当中也有this关键字,而 JavaScript 语言当中的this关键字因为具有运行期绑定的特性,JS 当中的这个this关键字的含义要丰富的多。现在来看看这个this到底有啥奥秘……

运行环境

this关键字指定的对象具体是指什么,这完全取决于函数的调用方式,JavaScript 中的函数的调用有以下几种方式:
作为函数调用
作为对象方法调用
作为构造函数调用

作为函数调用
var n = "Hello World!"; function example(){ console.log(this.n); } example(); //Hello World!
Run code
Cut to clipboard

    var n = 'Hello World!'; function example(){ this.n=0; } example(); console.log(n); //0
    Run code
    Cut to clipboard

      我们通过上面的两个例子,我们可以明确知道:当函数直接调用时,该函数的this关键字指向的就是全局对象window。此时上面例子的全局变量n其实就是window.n。

      作为对象方法调用
      function getAge(){ var y = new Date().getFullYear(); return y - this.birth; } var xiaoming = { name: '小明', birth: 1990, age: getAge }; console.log(xiaoming.age());//27 console.log(getAge()); //NaN var fn = xiaoming.age; console.log(fn()); //NaN
      Run code
      Cut to clipboard

        var name = 'Akita'; var dogs = { name:'Collie', showName: function(){ console.log(this.name); } }; console.log(dogs.showName()); //Collie var otherNmae = dogs.showName; console.log(otherName()); //Akita
        Run code
        Cut to clipboard

          如上面所示代码,当使用obj.xxx()的形式调用函数时,里面的this关键字指向的就是对象本身。但是我们还需要注意一点就是:在对象方法内部再次定义一个方法,该方法的this关键字又会重新指向全局对象window!如下代码所示:
          var xiaoming = { name: '小明', birth: 1990, age: function(){ function getAgeFromBirth(){ var y = new Date().getFullYear(); return y - this.birth; } return getAgeFromBirth(); } }; console.log(xiaoming.age()); //NaN
          Run code
          Cut to clipboard

            由于这是 JavaScript 一个巨大的设计错误。ECMA 决定在 strict 模式下(就是开头声明'use strict';)让函数的this指向undefined。因此,在 strict 模式下你会得到的错误就不是 NaN,而是TypeError:Cannot read property 'birth' of undefined。

            作为构造函数调用
            function Student(name){ this.name=name; } var xiaoming = new Student('小明'); console.log(xiaoming.name); //小明
            Run code
            Cut to clipboard

              上面这段代码中我们通过构造函数构造了一个新的对象xiaoming,那么this就会指向这个对象。

              指定 this 指向

              虽然在一个独立的函数调用中,根据是否是strict模式,this指向undefined或window,不过,我们还是可以控制this的指向的!

              要指定函数的this指向哪个对象,可以用函数本身的apply方法,它接收两个参数,第一个参数就是需要绑定的this变量,第二个参数是Array,表示函数本身的参数。

              用apply修复getAge()调用:
              function getAge() { var y = new Date().getFullYear(); return y - this.birth; } var xiaoming = { name: '小明', birth: 1990, age: getAge }; xiaoming.age(); // 25 getAge.apply(xiaoming, []); // 25
              Run code
              Cut to clipboard

                此时利用apply()将getAge()的this指向了xiaoming这个对象,因此函数执行正确。

                参考
                方法 - 廖雪峰的官方网站
                Javascript 深入浅出this