JavaScript里的this

https://wangdoc.com/javascript/oop/this.html

this在有些地方会让人感觉很困惑,这里记录下。

知识点

  1. this指向谁,是实际运行时才决定的。this指向当前运行环境(这里的运行环境是一个JavaScript对象)。比如下面代码的this指向对象A。
var A = {
    
    
  name: '张三',
  describe: function () {
    
    
    return '姓名:'+ this.name;
  }
};
  1. 在全局运行环境时,this指向window对象。

问题来了

  1. 猜下以下控制台会输出什么?
var obj ={
    
    
  foo: function () {
    
    
    console.log(this);
  }
};
// 情况一
(obj.foo = obj.foo)() 
// 情况二
(false || obj.foo)() 
// 情况三
(1, obj.foo)() 
//情况四
obj.foo()

除了最后一个,其他都输出window对象。情况四中,foo函数四obj对象调用的,拥有obj的对象环境。前三种情况都把obj.foo函数提出来了,运行环境不是obj对象,而是全局对象。

不同对象有不同运行环境,下面的例子就很好解释了。

var a = {
    
    
  p: 'Hello',
  b: {
    
    
    m: function() {
    
    
      console.log(this.p);
    }
  }
};

a.b.m()

b对象里面没有p属性,所以会输出undefined,如果没有开启严格模式,会从window对象找p属性。

  1. 多层属性
var o = {
    
    
  f1: function () {
    
    
    console.log(this);
    var f2 = function () {
    
    
      console.log(this);
    }();
  }
}

o.f1()

第二个this指向window对象(没开严格模式的话,之后也一样)

  1. 数组遍历里
var o = {
    
    
  v: 'hello',
  p: [ 'a1', 'a2' ],
  f: function f() {
    
    
    this.p.forEach(function (item) {
    
    
      console.log(this.v + ' ' + item);
    });
  }
}

o.f()

第二个this不指向o对象

  1. 回调里
var o = new Object();
o.f = function () {
    
    
  console.log(this === o);
}

// jQuery 的写法
$('#button').on('click', o.f);

在实际执行里,f的运行环境不是在o对象了

解决方案

  1. 数字遍历、回调或多层里,提前用其他变量存起this
var o = {
    
    
  v: 'hello',
  p: [ 'a1', 'a2' ],
  f: function f() {
    
    
    var that = this;
    this.p.forEach(function (item) {
    
    
      console.log(that.v+' '+item);
    });
  }
}

这里用了that,that明确指向上层的this

  1. 绑定this,使其指向特定值
//1. call方法。制定函数内部的this(只是第一层,不是所有的this)指向传入参数。若没参数,默认全局对象。若为基本类型,将其封装。
var obj = {
    
    };

var f = function () {
    
    
  return this;
};

f() === window // true
f.call(obj) === obj // true

//2. apply方法。跟call方法一样,但传入的第二个参数是数组,call可以传入多个参数。以下代码等价
f.call(null, 1, 1) // 2
f.apply(null, [1, 1]) // 2
//apply这个可以做到很多神奇的操作,可以看最上面的链接

//3. bind方法,也是使this指向参数,但会返回一个函数
var counter = {
    
    
  count: 0,
  inc: function () {
    
    
    this.count++;
  }
};

var func = counter.inc.bind(counter);
func();
counter.count // 1

//还能绑定到其他对象
var counter = {
    
    
  count: 0,
  inc: function () {
    
    
    this.count++;
  }
};

var obj = {
    
    
  count: 100
};
var func = counter.inc.bind(obj);
func();
obj.count // 101

猜你喜欢

转载自blog.csdn.net/ZhaoBuDaoFangXia/article/details/101119295
今日推荐