javascript中的this

Table of Contents

ES5

this的指向分为4种:

隐式的this指向

作为对象的方法调用,this指向的是当前对象

var obj = {
    a: 1,
    getA: function(){
        console.log(this == obj); // true
        console.log(this.a); // 1
    }
}
obj.getA();

硬指定的this

作为普通函数调用,this指向的是全局对象

name = 'globalName';
var getName = function(){
  console.log(this == window);
  console.log(name);
};
getName();

或者 将对象的方法加入全局对象中,会改变原本的this指向

name = 'globalName';
var myObject = {
    name: "sven",
    getName: function(){
      console.log(this == window);
      console.log(this.name);
    }
}
var getName = myObject.getName; //主要是这一句
getName();  //globalName

当this在普通函数里面被用到时,this指向的是一个全局对象,在浏览器上是window,在nodejs上是global

构造函数调用

构造函数的外表和普通函数一样,它们主要区别于调用的方式,构造函数需要用 new运算符,在这里this指向的是一个局部对象,即这个返回的对象

var MyClass = function(){
  console.log(this == window);
  this.name = "sven";
}
var obj = new MyClass();
console.log(obj.name);

apply、call和bind

Function.prototype.call或Function.prototype.apply的调用,与普通函数不一样,call和apply可以动态地修改this的指向,bind也一样,只不过bind不是立刻执行的

var obj1 = {
    name: 'sven',
    getName: function(){
      console.log(this);
      console.log(this.name);
    }
};
var obj2 = {
    name: 'anne',
};
obj1.getName();  //输出:sven
obj1.getName.call(obj2);  //输出:anne
var getName = obj1.getName; // 把对象函数的方法加入到全局作用域中,对象的属性无法访问
getName = getName.bind(obj1); // 使用bind方法把这个方法绑定到obj1上
getName();

博客内容参考自JavaScript设计模式与开发实践,[p24-p27]

ES6

箭头函数内部的this指向动态变化

因为箭头函数内部的this后一直会向上级作用域进行查找 也因为这个原因,它不可以使用在Vue的选项属性或者回调函数中

比如下面的例子

  1. 上级是全局作用域 > 上级就是全局作用域,所以this指向全局作用域
var a = () => {
  console.log(this == window);
}
a();
  1. 上级是局部作用域
var name= "全局";
var test =  (callback) => {
  var name = "局部";
  (() => {
    console.log(this.name); // 局部
    })(); 
}
test();