Javascript 中的 this 关键字

发表于: 2015-09-16分类于:JavaScript

在 JavaScript 中有4种函数调用形式

  • 方法调用模式
  • 普通函数调用模式
  • 构造器调用模式
  • apply调用模式

不同的函数调用形式,函数中的 this 值也不同,下面来剖析各种情况下的 this 值。

方法调用模式

一个函数被保存为一个对象的方法时,函数内部的 this 指的就是当前这个对象。

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

obj.sayName(); // JavaScript

普通函数调用模式

当一个函数并非为某个对象的方法来调用的时候。函数内部的 this 绑定到全局对象。在严格模式下是 undefined。

name = 'Java';
var obj = {
    sayName:function(){
        console.log(this.name);
    },
    name:'JavaScript'
}
// 这里将一个对象的方法赋予一个变量,然后在调用该变量,这个时候就是一次普通的函数调用,this 值为全局对象
var sayName = obj.sayName;

sayName(); // Java

有时候我们希望在函数内部的调用的函数中的this能是外部函数的this。采用的补救方法是使用一个闭包,在外部函数中将this赋给一个that然后在内部函数中使用that来取得外部函数的this的引用,或者使用 bind 方法。

var obj = {
    sayName:function(){
        var that = this;
        var getFullName = function(){
            return  that.firstname + that.lastname;
        }
        console.log(getFullName());
    },
    firstname:'w',
    lastname:'y'
}

obj.sayName();

或者使用 bind :

var obj = {
    sayName:function(){
        var getFullName = function(){
            return  this.firstname + this.lastname;
        }.bind(this);
        console.log(getFullName());
    },
    firstname:'w',
    lastname:'y'
}

obj.sayName();

构造器调用模式

如果函数前面带上new来调用,那么将创建一个以该函数的 prototype 对象为原型的新对象,然后将 this 绑定至该对象上面。最后如果构造函数返回的不是一个对象,那么就将返回 this 。具体过程需要参看 new 的过程。

new 关键字的作用是创建一个对象,当一个函数使用 new 来调用的时候其实际上进行了下面的几个步骤:

  1. 创建一个空对象 obj
  2. 将这个 obj 的 proto 即:obj.proto 指向该函数的原型
  3. 执行该函数,并将函数中的 this 映射为 该空对象 obj。
  4. 最后如果该函数有返回值,而且返回值是对象,那么就返回这个对象。如果没有返回值,或者返回值不是对象,那么 new 的结果就是上面步骤构造出来的对象 obj。

apply 与 call 调用模式

apply 方法接受两个参数,第一个是将被绑定到 this 的值,第二个是一个参数数组。call 类似与 apply 只是参数形式不同罢了。

name = 'Java';
var obj = {
    name:'JavaScript'
}

var sayName = function(){
    console.log(this.name);
}

sayName.apply(obj);  // JavaScript