一、 在全局作用域中调用一个函数时,this总是指向Global对象(浏览器中就是window对象)

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

二、 当函数作为对象里的方法被调用时,this指向该对象

var name = 'May';
var obj = {
  name: 'Lily',
  getName: function() {
    console.log(this.name); // 'Lily'
  }
}
obj.getName(); 

三、 当一个函数用作构造函数时(使用new关键字),this指向正在构造的新对象。如果构造函数返回的值不是一个对象,则默认返回this对象,看例子。

function Name() {
  this.name = 'May';
}
var obj = new Name();
console.log(obj.name); // 'May' 
function Name() {
  this.name = 'May';
  return 'Lily';
}
var obj = new Name();
console.log(obj.name); // 'May',因为返回的是字符串而不是对象 
function Name() {
  this.name = 'May';
  return { name: 'Lily' };
}
var obj = new Name();
console.log(obj.name); // 'Lily' 

四、事件监听中的this

被内联处理函数调用时,this指向所在的DOM元素

<div id="test" onclick="alert(this.id)">Click</div> 

上面的alert显示test,但只有外层代码的this是这样的,如果像以下这种情况,this会指向window对象(非严格模式下),所以alert显示undefined,因为window中没有定义id

<div id="test" onclick="(function(){alert(this.id);})()">
  Click2
 </div> 

当作为一个DOM事件处理函数时,this指向触发事件的元素

<div id="test">A</div>
document.getElementById('test').onclick = function() {
    console.log(this.id); // test元素
} 

五、apply()和call()

这两个方法的用途都是在特定的作用域中调用函数,等同于设置函数体内this对象的值,改变this指向。

apply()接收两个参数,第一个是在其中运行函数的作用域(this值),第二个是参数数组。

call()与apply()方法作用相同,区别仅在于接受参数的方式不同,call()第一个参数是this值,传递给函数的参数必须逐个列出来。

var name = 'May';
var obj = {
    name: 'Lily',
    getName: function() {
        console.log(this.name);
    }
}
obj.getName.apply({ name: 'Mary' }); // 'Mary'
obj.getName.apply(window); // 'May'

obj.getName.call({ name: 'Jay' }); // 'Jay'
obj.getName.call(window); // 'May' 
// apply()与call()传参示例
function add(a, b) {
    return a + b + this.num;
}
var o = { num: 1 };
console.log(add.apply(o, [4, 3])); // 4+3+1 = 8
console.log(add.call(o, 2, 2)); // 2+2+1 = 5 

六、bind()

bind()方法被调用时,返回一个新的函数,新的函数的this被永久绑定到了bind的第一个参数(bind的其余参数将作为新函数的参数供调用时使用)

var name = 'May';
var obj = {
    name: 'Lily',
    getName: function(name) {
        console.log(this.name);
        console.log(name);
    }
}
var getName = obj.getName.bind({ name: 'Bind' }, 'Test');
getName(); // 'Bind' 'Test' 

七、箭头函数中的this

箭头函数的this值是定义时所在的对象而不是执行时所在的对象。

var name = 'May';
var obj = {
  name: 'Lily',
  getName: () => {
      console.log(this.name);
  }
}
obj.getName(); // 输出的是'May'而不是'Lily' 

总结:

绝大多数情况下,函数的this值取决于函数执行时的环境,而非函数声明时的环境。但箭头函数的this值保持为闭合词法上下文的值,就是定义时所在的对象而不是执行时所在的对象。


望记
183 声望7 粉丝