Typescript中的类方法与属性函数与属性箭头函数之间有什么区别? [英] What is the difference between class method vs property function vs property arrow function in typescript?

查看:450
本文介绍了Typescript中的类方法与属性函数与属性箭头函数之间有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道-类方法,作为函数的类属性和作为箭头函数的类属性之间有什么区别?在不同的方法变体中,"this"关键字的行为是否有所不同?

I was wondering - what is the difference between class method, class property which is a function and class property which is an arrow function? Does the 'this' keyword behave differently in the different variants of the method?

class Greeter {

  constructor() {
    this.greet();
    this.greet2();
    this.greet3();
  }

  greet() {
    console.log('greet1', this);
  }

  greet2 = () => {
    console.log('greet2', this);
  }

  greet3 = function() {
    console.log('greet3', this);
  }
}


let bla = new Greeter();

已编译打字稿的javascript输出:

javascript output from the compiled typescript:

var Greeter = /** @class */ (function () {
function Greeter() {
    var _this = this;
    this.greet2 = function () {
        console.log('greet2', _this);
    };
    this.greet3 = function () {
        console.log('greet3', this);
    };
    this.greet();
    this.greet2();
    this.greet3();
}
Greeter.prototype.greet = function () {
    console.log('greet1', this);
};
return Greeter;
}());
var bla = new Greeter();

我的TypeScript版本是3.4.5

My TypeScript version is 3.4.5

推荐答案

所有3个版本之间都存在差异.区别在于3个方面:

There are differences between all 3 versions. This differences are in 3 areas:

  1. 运行时this是谁
  2. 分配功能的地方
  3. 打字稿中的类型是什么.
  1. Who is this at runtime
  2. Where the function is assigned
  3. What is the type of this in typescript.

让我们从它们在相同的地方开始.考虑带有一个类字段的此类:

Lets start with where they work just the same. Consider this class, with a class field:

class Greeter {
  constructor(private x: string) {
  }
  greet() {
    console.log('greet1', this.x);
  }

  greet2 = () => {
    console.log('greet2', this.x);
  }

  greet3 = function () {    
    // this is typed as any 
    console.log('greet3', this.x);
  }
}

let bla = new Greeter(" me");

使用此类,所有3个函数调用将按预期打印:'greet* me'bla

With this class all 3 function calls will print as expected: 'greet* me' when invoked on bla

bla.greet()
bla.greet2()
bla.greet3()

运行时是谁

箭头函数从声明上下文中捕获this,因此始终保证greet2中的this是创建此函数的类实例.其他版本(方法和功能)不提供此类保证.

Arrow functions capture this from the declaration context, so this in greet2 is always guaranteed to be the class instance that created this function. The other versions (the method and function) make no such guarantees.

因此在此代码中,并非所有3个都打印相同的文本:

So in this code not all 3 print the same text:

function call(fn: () => void) {
  fn();
}

call(bla.greet) // greet1 undefined 
call(bla.greet2) //greet2 me
call(bla.greet3) // greet3 undefined

当将函数作为事件处理程序传递给另一个组件时,这一点尤其重要.

This is particularly important when passing the function as an event handler to another component.

分配功能的地方

Class方法(例如greet),在构造函数中分配了字段初始化(例如greet2greet3).这意味着greet2greet3将具有更大的内存占用空间,因为每次实例化Greeter时,它们都需要分配一个新的闭包.

Class methods (such as greet) are assigned on the prototype, field initializations (such as greet2 and greet3) are assigned in the constructor. This means that greet2 and greet3 will have a larger memory footprint as they require an allocation of a fresh closure each time Greeter is instantiated.

打字稿中的此类型是什么.

Typescript在方法(greet)和箭头函数(greet2)中都将this作为Greeter的实例,但是将在greet3中键入this.如果您尝试在noImplictAny

Typescript will type this as an instance of Greeter in both the method (greet) and the arrow function (greet2) but will type this as any in greet3. This will make it an error if you try to use this in greet3 under noImplictAny

何时使用它们

  1. 如果该函数不会作为事件处理程序传递给另一个组件,请使用方法语法(除非您使用bind或其他方法来确保this仍是该类的实例)

  1. Use the method syntax if this function will not be passed as an event handler to another component (unless you use bind or something else to ensure this remains the instance of the class)

当您的函数将被传递给其他组件并且需要访问函数内部的this时,请使用箭头函数语法.

Use arrow function syntax when your function will be passed around to other components and you need access to this inside the function.

为此,真的不能想到一个好的用例,通常避免使用.

Can't really think of a good use case for this, generally avoid.

这篇关于Typescript中的类方法与属性函数与属性箭头函数之间有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆