Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/456.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript typescript中的类方法、属性函数和属性箭头函数有什么区别?_Javascript_Typescript_Oop_Ecmascript Next_Class Fields - Fatal编程技术网

Javascript typescript中的类方法、属性函数和属性箭头函数有什么区别?

Javascript typescript中的类方法、属性函数和属性箭头函数有什么区别?,javascript,typescript,oop,ecmascript-next,class-fields,Javascript,Typescript,Oop,Ecmascript Next,Class Fields,我想知道-类方法、类属性(函数)和类属性(箭头函数)之间的区别是什么?“this”关键字在方法的不同变体中的行为是否不同 class Greeter { constructor() { this.greet(); this.greet2(); this.greet3(); } greet() { console.log('greet1', this); } greet2 = () => { console.log('gree

我想知道-类方法、类属性(函数)和类属性(箭头函数)之间的区别是什么?“this”关键字在方法的不同变体中的行为是否不同

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输出:

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

关键字差异: 在上面的例子中,这三个函数都具有相同的
this
,但是当您将该方法传递给另一个函数时,您将看到不同之处

类迎宾员{
构造函数(){
}
问候{
console.log(this);
}
greet2=()=>{
console.log(this);
}
greet3=函数(){
console.log(this);
}
}
设bla=新迎宾员();
函数包装器(f){
f();
}
包装器(bla.greet)//未定义
包装器(bla.greet2)//问候器

包装器(bla.greet3)//未定义
所有3个版本之间都存在差异。这种差异存在于3个方面:

  • 运行时谁是这个
  • 分配功能的位置
  • typescript中此的类型是什么
  • 让我们从他们工作的地方开始。考虑这个类,具有类字段:

    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上调用时

    bla.greet()
    bla.greet2()
    bla.greet3()
    
    运行时这是谁

    箭头函数从声明上下文捕获
    ,因此
    greet2中的
    始终保证是创建此函数的类实例。其他版本(方法和函数)没有这样的保证

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

    function call(fn: () => void) {
      fn();
    }
    
    call(bla.greet) // greet1 undefined 
    call(bla.greet2) //greet2 me
    call(bla.greet3) // greet3 undefined
    
    当将函数作为事件处理程序传递给另一个组件时,这一点尤为重要

    分配功能的位置

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

    typescript中的类型是什么。

    Typescript将在方法(
    greet
    )和箭头函数(
    greet2
    )中键入
    this
    ,作为
    Greeter
    的一个实例,但将在
    greet3
    中键入
    this
    。如果您在
    noImplictAny

    何时使用它们

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

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

  • 不能真正想到一个好的用例,通常避免


  • 首先,第二个和第三个错误出现了。当我在我的计算机上编译它时,没有错误(tsc./test.ts)。我可以获得已编译的javascript并在浏览器控制台中运行,没有任何问题。@如果您查看编译结果,两者之间的差异应该很明显。@Bergi如果答案对我来说很清楚,我不会问这个问题。太好了!现在您可以看到,它们都使用while;在所有3种方法中,我可以说console.log(this.str),它输出“我的字符串”。但我想知道——在所有3种方法中,“这”真的是相同的吗?@Combine我在答案的末尾添加了更多的解释。请检查它。关于
    ,箭头函数捕获
    常规函数没有区别是什么意思?如果在函数变量中传递该方法,会产生巨大的影响。它仍然说“这三个函数都有相同的特性”哪个明显不正确?@Bergi我的意思是,在给定的代码中,当OP从
    构造函数调用函数时,这三个函数都具有相同的
    this