this

147 阅读2分钟

有时候一不写this,就报一个undefined,this的使用简直前端开发的要点啊,this真是无处不在,用的地方简直太多了,尤其是this的指向经常搞得人头晕啊。

this是什么

在面向对象语言中,this是关键字,是对当前对象的引用,而在JavaScript中的this是动态绑定的,或者是运行是绑定的,导致this关键字代表多重含义。

普通函数this

默认指向

  • 非严格模式(单独使用 this,则它指向全局(Global)对象。 在浏览器中,window 就是该全局对象为 [object Window])
var x = this;

  • 严格模式(如果单独使用,this 也是指向全局(Global)对象。)
"use strict";
var x = this;

方法中使用this

  • 简单
var age = 18;
function showAge () {
  var age = 98;
  console.log('my age is: ' + this.age);
}
showAge();//output:my age is: 18

showAge没有被打点调用,所以指向的是全局对象window,所以this.age就是18。

  • 复杂(带有定时器---异步函数)
var age = 18;
var obj = {
    age : 98,
    showAge : function () {
      setTimeout(function () {
        console.log('my age is: ' + this.age);        
      }, 3000);
    
    }
}
obj.showAge();//output:my age is: 18


是不是很惊讶,这不是应该98吗,怎么还是18啊,首先obj.showAge()调用的对象是obj,调用的是showAge()函数,其次setTimeout只是一个定时器不执行(没有被调用),this.age在定时器函数中,所以this的指向还是window,故输出的结果还是18。

构造函数里的this

function Person (name, age) {
    this.name = name;
    this.age = age;
    this.introduceYourself = function () {
      console.log('my name is ' + this.name, 'and I\'m ' + this.age + ' years old.');
    }
}
var person = new Person('丫蛋', 18);
person.introduceYourself ();//output:my name is 
丫蛋 and I'm 18 years old.

call、bind、apply改变this的指向

  • call apply bind 的作用和使用方法 call apply 都是改变一个函数的this指向并执行该函数,区别是传参列表不同,call(obj, 参数1, 参数2, ...) apply(obj, arguments) bind是改变一个函数的this指向并返回一个新的函数,传参结合call和apply的,只接收第一次绑定的this

var obj = {
    age : 100,
    showAge : function () {
      console.log('my age is: ' + this.age);
    }
}
var obj2 = {
    age : 18
}
obj.showAge.call(obj2);//output:my age is: 18

为什么是18呢?showAge的调用对象明明是obj,但由于用了call,this的指向对象变成了obj2,所以结果为18。

箭头函数this

箭头函数没有this,它的this是继承而来(引用外层的)。

function foo() {
  setTimeout(() => {
    console.log('Array:', arguments);
  }, 100);
}
 
foo(2, 4, 6, 8)
// Array: [2, 4, 6, 8]


总结

普通函数

  • 方法调用中, this 指向调用它所在方法的对象。
  • 单独使用 this,它指向全局(Global)对象,默认指向window。
  • 严格模式下函数是没有绑定到 this 上,这时候 this 是 undefined。
  • apply、 call 、bind允许切换函数执行的上下文环境(context),即 this 绑定的对象,可以将 this 引用到任何对象。
  • 构造函数中this指向new出来的对象。

箭头函数

  • this指向定义它的对象。