阅读 103

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

1、this指向常见的情形

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

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

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

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

var name = 'global';
var b = {
  name: 'b的name',
  fn() {
   console.log(this.name);
  }
}
b.fn(); // 打印的是 'b的name'
情形二.png
情形三:this只会指向最后一次调用的对象
var name = 'global';
var c = {
  name: 'c的name',
  fn() {
    console.log(this.name);
  }
}
window.c.fn();
情形三.png
情形四:当最后一次调用的对象内部没有该属性时
var name = 'global';
var d = {
  fn() {
    console.log(this.name);
  }
}
window.d.fn();
情形四.png
情形五:比较 坑!的情形

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

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

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();
情形六.png

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

image.png

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

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

这样指向就修改正确了。

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)
}
image.png

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

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

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

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

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

作者:听书先生

原文链接:https://www.jianshu.com/p/1852af464ef7

文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐