js设计模式-this

109 阅读1分钟

JS中,this总指向一个对象,而具体指向那个对象是在运行时基于函数的执行环境动态绑定的,而非函数被声明时的环境。this的指向大致可以分为以下4种。

  • 作为对象的方法调用
const obj = {
  name: 'test',
  getName() {
    console.log(obj === this) // true
    console.log(this.name) // test
  }
}
obj.getName()
  • 作为普通函数调用 当函数作为普通函数调用时,this总指向全局变量,一般是window对象。
 window.name = 'test1'
const obj = {
  name: 'test',
  getName() {
    console.log(window === this) // true
    console.log(this.name) // test1
  }
}
const getName = obj.getName;
getName();
  • 构造器调用 JS用new运算符调用函数时,该函数为构造器函数,调用时总会返回一个对象,通常情况下,构造器里的this指向返回的这个对象。
function MyClass () {
  this.name = 'seven';
}
const obj = new MyClass();
console.log(obj.name) // seven

但是在构造器里面如果返回的是一个对象,那么运算结构最终返回这个对象,而不是之前的this;

function MyClass () {
  this.name = 'seven';
  return {
    name: 'seven1'
  }
}
const obj = new MyClass();
console.log(obj.name) // seven1

如果在构造器里面不显式的返回任何数据,或者返回一个非对象类型的数据,就不会有上述问题:

function MyClass () {
  this.name = 'seven';
  return 'seven1'
}
const obj = new MyClass();
console.log(obj.name) // seven
  • Function.prototype.call或Function.prototype.apply调用 call和apply可以动态改变传入函数的this
const obj = {
  name: 'seven',
  getName() {
    return this.name
  }
}
const obj1 = {
  name: 'seven1',
}
console.log(obj.getName()) // seven
console.log(obj.getName.call(obj1)) // seven1