TypeScript 中this

        今天被typeScript中的this的指向弄懵了,在网上看了些资料,坐下总结:

        javaScript 有一套完全不同于其它语言的对 this 的处理机制。this的指向不仅是由定义函数的方式和位置决定,同时还严重受到函数调用方式的影响


1. 在全局范围内

        this 指向全局对象,浏览器是 window 对象, node 是 global 对象

TypeScript 中的this:

        1 函数中的this 测试如下:

// 普通函数
function fun1(a:number)
{
    this.a = a;
    console.log("普通函数",this);
}
//表达式声明
var fun2 = function (a:number){
    this.a = a;
    console.log("表达式声明",this);
}
//lambda 函数
var fun3 = (a:number) => {
    this.a = a;
    console.log("Lambda函数",this)
}
fun1(14);
fun2(15);
fun3(16);
console.log("this:::",this)

编译后的js代码:

var _this = this;
// 普通函数
function fun1(a) {
    this.a = a;
    console.log("普通函数", this);
}
//表达式声明
var fun2 = function (a) {
    this.a = a;
    console.log("表达式声明", this);
};
//lambda 函数
var fun3 = function (a) {
    _this.a = a;
    console.log("Lambda函数", _this);
};
fun1(14);
fun2(15);
fun3(16);
console.log("this:::", this);

运行输出结果:

 注意:如果tsconfig.json 中设置的是严格模式,这种函数中的this等于undefined,是不能这么用的,报错:

this' implicitly has type 'any' because it does not have a type annotation.ts(2683)

any

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

// 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();

编译后的js代码:

// 1.无嵌套类和无嵌套函数的普通类
var Test = /** @class */ (function () {
    function Test() {
        var _this = this;
        this.a = "outer";
        this.fn2 = function () {
            console.log("Test.fn2(),表达式声明:" + this.a);
        };
        this.fn3 = function () {
            console.log("Test.fn3(),箭头函数:" + _this.a);
        };
    }
    Test.prototype.fn1 = function () {
        console.log("Test.fn1(),普通函数:" + this.a); //如果是严格模式就会报错
    };
    return Test;
}());
var x = new Test();
x.fn1();
x.fn2();
x.fn3();

 输出的结果表明:this始终指向所在类的实例

 

 3.嵌套类中:

// 嵌套类
  class Test_q {
    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); //指向的是outer
      },
    }
   
  }
  var xq:Test_q = new Test_q();
  xq.b.fn1();
  xq.b.fn2();
  xq.b.fn3();

 转换后的js代码:

// 嵌套类
var Test_q = /** @class */ (function () {
    function Test_q() {
        var _this = this;
        this.a = "outer";
        // 嵌套类b
        this.b = {
            a: "inner",
            fn1: function () {
                console.log("Test.b.fn1(),普通函数:" + this.a);
            },
            fn2: function () {
                console.log("Test.b.fn2(),表达式声明:" + this.a);
            },
            fn3: function () {
                console.log("Test.b.fn3(),箭头函数:" + _this.a); //指向的是outer
            },
        };
    }
    return Test_q;
}());
var xq = new Test_q();
xq.b.fn1();
xq.b.fn2();
xq.b.fn3();

输出的结果说明: 嵌套类里的普通函数和表达式声明函数的函数体里的this指向此嵌套类的实例,箭头函数函数里的this指向上级类的实例

4 . 嵌套函数中测试:

// 嵌套函数
class Test_qf {
    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 xqf: Test_qf = new Test_qf();
  xqf.fn();

编译成的js代码:

// 嵌套函数
var Test_qf = /** @class */ (function () {
    function Test_qf() {
        this.a = "outer";
    }
    Test_qf.prototype.fn = function () {
        var _this = this;
        var a = "inner";
        function fn1() {
            console.log("Test.fn()->fn1(),普通函数:" + this.a);
        }
        var fn2 = function () {
            console.log("Test.fn()->fn2(),表达式声明:" + this.a);
        };
        var fn3 = function () {
            console.log("Test.fn()->fn3(),箭头函数:" + _this.a);
        };
        function fn4() {
            console.log("Test.fn()->fn4(),普通函数:" + a);
        }
        fn1();
        fn2();
        fn3();
        fn4();
    };
    return Test_qf;
}());
var xqf = new Test_qf();
xqf.fn();

测试输出结果:嵌套的普通函数,声明表达式函数中this 指向的还是整个文件,

5 当使用 Function.prototype 上的 call 或者 apply 方法时,函数内的 this 将会被 显式设置为函数调用的第一个参数。

// call or apply 调用
function juggle() {
    let result = 0;
    for (let n=0; n<arguments.length; n++) {
        result += arguments[n];
    }
    this.results = result;
}
let ninja1 = {};
let ninja2 = {};
juggle.apply(ninja1, [1,2,3,4]);
juggle.call(ninja2, 5,6,7,8);
console.log(ninja1); // { results: 10 }
console.log(ninja2); // { results: 26 }

输出结果:

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值