TypeScript类中的this作用域详解

TypeScript中有三种声明函数的方法:

// 普通函数
fn1() {
  console.log("XJL");
}

// 表达式声明
var fn2 = function () {
  console.log("XJL");
}

// 箭头函数声明
var fn3 = () => {
  console.log("XJL");
}

现在我们来演示一下,在TypeScript的类的各种情况下this作用域的范围

 

1.无嵌套类和无嵌套函数的普通类

class Test {
  a: string = "outer";

  fn1() { 
    console.log("Test.fn1(),普通函数:" + this.a);
  }

  fn2 = function() {
    console.log("Test.fn2(),表达式声明:" + this.a);
  }

  fn3 = () => {
    console.log("Test.fn3(),箭头函数:" + this.a);
  }
}

var x: Test = new Test();
x.fn1();
x.fn2();
x.fn3();

 

输出:

Test.fn1(),普通函数:outer
Test.fn2(),表达式声明:outer
Test.fn3(),箭头函数:outer

结论:在这种情况下,this始终指向所在类的实例。

 

2.嵌套类

class Test {
  a: string = "outer";

  // 嵌套类b
  b = {
    a: "inner",

    fn1() { 
      console.log("Test.b.fn1(),普通函数:" + this.a);
    },

    fn2: function() { 
      console.log("Test.b.fn2(),表达式声明:" + this.a);
    },

    fn3: () => {
      console.log("Test.b.fn3(),箭头函数:" + this.a);
    },
  }

}

var x: Test = new Test();
x.b.fn1();
x.b.fn2();
x.b.fn3();

输出:

Test.b.fn1(),普通函数:inner
Test.b.fn2(),表达式声明:inner
Test.b.fn3(),箭头函数:outer

结论: 嵌套类里的属性申明时的this指向上级类的实例; 嵌套类里的普通函数和表达式声明函数的函数体里的this指向此嵌套类的实例,箭头函数函数里的this指向上级类的实例。

 

3.嵌套函数

class Test {
  a: string = "outer";

  fn() {
    var a = "inner";
    
    function fn1() {
      console.log("Test.fn()->fn1(),普通函数:" + this.a);
    }

    var fn2 = function () {
      console.log("Test.fn()->fn2(),表达式声明:" + this.a);
    }

    var fn3 = () => {
      console.log("Test.fn()->fn3(),箭头函数:" + this.a);
    }

    function fn4() {
      console.log("Test.fn()->fn4(),普通函数:" + a);
    }

    fn1();
    fn2();
    fn3();
    fn4();
  }
}

var x: Test = new Test();
x.fn();

输出:

Test.fn()->fn1(),普通函数:undefined
Test.fn()->fn2(),表达式声明:undefined
Test.fn()->fn3(),箭头函数:outer
Test.fn()->fn4(),普通函数:inner

结论:在嵌套函数体里,箭头函数的this可指向fn函数所在实例;普通函数和表达式声明函数的函数体里的this即不指向Test实例,也不指向fn(),据观察,而是指向最根部的window实例。fn4()说明了如要调用fn()里声明的变量只要直接写变量名即可。

总结:在嵌套类和嵌套函数中,具有穿透力的就是箭头函数,它总能穿过所在的类和函数,获取到上级类的属性,是什么原因造成这样的呢?我们来看一下TS转为JS后的代码

TS代码

// 含有箭头函数的类
class Test1 {
  a: string = "outer";

  fn = () => {
    console.log(this.a);
  }
}

// 不含有箭头函数的类
class Test2 {
  a: string = "outer";

  fn() {
    console.log(this.a);
  }
}

通过tsc命令转为JS代码后

// 含有箭头函数的类
var Test1 = /** @class */ (function () {
    function Test1() {
        var _this = this;
        this.a = "outer";
        this.fn = function () {
            console.log(_this.a);
        };
    }
    return Test1;
}());

// 不含有箭头函数的类
var Test2 = /** @class */ (function () {
    function Test2() {
        this.a = "outer";
    }
    Test2.prototype.fn = function () {
        console.log(this.a);
    };
    return Test2;
}());

我们可以看到含有箭头函数的类在转为js代码后,会多一条“var _this=this;”的语句,当箭头函数要引用this时,都是调用_this,这就是穿透的秘诀~~

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值