this到底指的是谁

2019-10-09  本文已影响0人  mah93

JavaScript中的this依赖于函数的调用方式,因此把this称为调用上下文很合适。

先来一个最简单的例子

function ask(){
  console.log(this.name)
}
var li_lei = {
  name: "han mei mei",
  ask: ask
}

`这两个方法分别输出什么`
li_lei.ask()             => "li lei"
han_mei_mei.ask()        => "han mei mei"

稍微复杂一点

var li_lei = {
  name: "li lei",
  ask: function (){
    console.log(this.name)
  }
}

var han_mei_mei = {
  name: "han_mei_mei",
  ask: li_lei.ask
}

`这两个方法分别输出什么`
li_lei.ask()             => "li lei"
han_mei_mei.ask()        => "han mei mei"


根据上面的两个例子引出一个概念,请记住:

function中的this一般情况下表示的是调用对象(调用对象.方法名())

那么接下来需要考虑一个问题,在js里经常把function作为回调函数传来传去,用什么手段可以让function中的this保持不变?

让function中的this“保持不变”

使用bind方法

var li_lei = {
  name: "li lei",
  _ask: function(){
    console.log(this.name)
  }
}
li_lei.ask = li_lei._ask.bind(li_lei)

var han_mei_mei = {
  name: "han mei mei"
}
han_mei_mei.ask = li_lei.ask

`这两个方法分别输出什么`
li_lei.ask()             => "li lei"
han_mei_mei.ask()        => "li lei"

改成用类来举例(类的声明用es6语法)

class LiLei {
  constructor() {
    this.name = "li lei";
    this.ask = this._ask.bind(this);
  }
  _ask(){
    console.log(this.name);
  }
}

var li_lei = new LiLei();

class HanMeiMei {
  constructor(li_lei_instance){
    this.name = "han mei mei";
    this.ask = li_lei_instance.ask
  }
}

var han_mei_mei = new HanMeiMei(li_lei)

`这两个方法分别输出什么`
li_lei.ask()             => "li lei"
han_mei_mei.ask()        => "li lei

不使用bind实现同样的效果

class LiLei {
  constructor() {
    this.name = "li lei";
    
    var that = this;
    this.ask = function(){
      console.log(that.name);
    }
  }
}

var li_lei = new LiLei();

class HanMeiMei {
  constructor(li_lei_instance){
    this.name = "han mei mei";
    this.ask = li_lei_instance.ask
  }
}

var han_mei_mei = new HanMeiMei(li_lei)

`这两个方法分别输出什么`
li_lei.ask()             => "li lei"
han_mei_mei.ask()        => "li lei

变复杂一点

class LiLei {
  constructor() {
    this.name = "li lei";
    this.ask = this.bind_ask();
  }
  
  bind_ask(){
    var that = this;
    var fun = function(){
      console.log(that.name);
    }
    return fun;
  }
}

var li_lei = new LiLei();

class HanMeiMei {
  constructor(li_lei_instance){
    this.name = "han mei mei";
    this.ask = li_lei_instance.ask
  }
}

var han_mei_mei = new HanMeiMei(li_lei)

`这两个方法分别输出什么`
li_lei.ask()             => "li lei"
han_mei_mei.ask()        => "li lei

使用ES6中的箭头函数来实现

class LiLei {
  constructor() {
    this.name = "li lei";
    this.ask = () => {
      console.log(this.name)
    };
  }
}

var li_lei = new LiLei();

class HanMeiMei {
  constructor(li_lei_instance){
    this.name = "han mei mei";
    this.ask = li_lei_instance.ask
  }
}

var han_mei_mei = new HanMeiMei(li_lei)

`这两个方法分别输出什么`
li_lei.ask()             => "li lei"
han_mei_mei.ask()        => "li lei

ES6中的箭头函数和普通的function在处理this上是有差别的,根据上面的例子你应该已经明白了:

ES6的箭头函数中的this,永远保持不变,一只表示声明时的this

上一篇 下一篇

猜你喜欢

热点阅读