0
点赞
收藏
分享

微信扫一扫

this指向的问题以及call()、apply()、bind()修改this指向

Sky飞羽 2021-09-19 阅读 66

1、this指向常见的情形

this的理解只需要记住: 它是指向的最后一次被调用的对象

情形一:没有对象调用的情况
var name = 'global';

function fn() {
  var name = 'inner';
  console.log(this.name); // global this指向的是最后一次被调用的对象!
}
fn(); // 等价于 window.fn(); 因此指向的是window全局

情形二:有对象去调用

对象去调用方法,this指向的最后一次调用的对象。

var name = 'global';
var b = {
  name: 'b的name',
  fn() {
   console.log(this.name);
  }
}
b.fn(); // 打印的是 'b的name'

情形三:this只会指向最后一次调用的对象
var name = 'global';
var c = {
  name: 'c的name',
  fn() {
    console.log(this.name);
  }
}
window.c.fn();

情形四:当最后一次调用的对象内部没有该属性时
var name = 'global';
var d = {
  fn() {
    console.log(this.name);
  }
}
window.d.fn();

情形五:比较 坑!的情形

把e中的fn()赋值给了f,但是f并没有对象去调用,此时依旧为window.f()

var name = 'global';
var e = {
  name: 'e的name',
  fn() {
    console.log(this.name);
  }
}
var f = e.fn;
f();

情形六:

demo方法被window调用,因此,内部的this指向依旧是window,内部函数fn()等价于this.fn()因此,打印的结果是global

var name = 'global';    
function demo() {
  var name = 'g的name';
  fn();
  function fn() {
    console.log(this.name);
  }
}
demo();

2、改变this的指向一:ES6中的箭头函数

ES6中的箭头函数是没有this指向的,如果在箭头函数中使用this,那么它指向的是上下文对象。

function Foo(){
    this.name = "Foo的name"
}
// 在原型对象上新增方法
Foo.prototype.getName = function(){
  console.log('getName打印的姓名:',this.name)
}
Foo.prototype.putName = function(){
  setTimeout(function(){
    this.getName()
  },100)
}
var f = new Foo();
f.putName();

这种情况下在setTimeout内部console.log一下this


发现指向的是全局对象window,这是因为ES5的写法带来的影响,如果换成ES6的箭头函数就会解决此类问题。

Foo.prototype.putName = function(){
  setTimeout(() => {
    console.log(this);
    this.getName()
  },100)
}


这样指向就修改正确了。

3、改变this的指向二:apply()

fn.apply(target, [argumentsList])

  • target:函数调用时绑定的这个对象
  • argumentsList:函数调用时预期的实参列表,该参数应该是一个类数组的对象

同样的使用之前的测试案例

function Foo(){
    this.name = "Foo的name"
}
// 在原型对象上新增方法
Foo.prototype.getName = function(){
  console.log('getName打印的姓名:',this.name)
}
Foo.prototype.putName = function(){
  setTimeout(function(){
    this.getName()
  },100)
}
var f = new Foo();
f.putName();

目前的this指向的是window全局对象,可以在函数末尾添加apply(f)去指定函数调用的实例对象f.

Foo.prototype.putName = function(){
     setTimeout(function(){
        console.log(this);
         this.getName()
    }.apply(f),100)
}


修改后的结果指向依旧是正确的

4、改变this的指向三:call()

Foo.prototype.putName = function(){
  setTimeout(function(){
    console.log(this);
    this.getName()
  }.call(f),100)
}

5、改变this的指向四:bind()

Foo.prototype.putName = function(){
  setTimeout(function(){
    console.log(this);
    this.getName()
  }.bind(f)(),100)
}

举报

相关推荐

0 条评论