Com*_*ine 7 javascript oop typescript
我想知道-类方法,作为函数的类属性和作为箭头函数的类属性之间有什么区别?在不同的方法变体中,“ 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();
Run Code Online (Sandbox Code Playgroud)
编辑:从编译的打字稿的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();
Run Code Online (Sandbox Code Playgroud)
我的TypeScript版本是3.4.5
Tit*_*mir 17
所有 3 个版本之间都存在差异。这种差异体现在 3 个方面:
this在运行时this打字稿中的类型是什么。让我们从它们工作的地方开始。考虑这个具有类字段的类:
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");
Run Code Online (Sandbox Code Playgroud)
有了这个类的所有3个函数调用将打印预期:'greet* me'在调用时bla
bla.greet()
bla.greet2()
bla.greet3()
Run Code Online (Sandbox Code Playgroud)
运行时这是谁
箭头函数this从声明上下文中捕获,因此thisingreet2始终保证是创建此函数的类实例。其他版本(方法和函数)没有这样的保证。
因此,在此代码中,并非所有 3 个都打印相同的文本:
function call(fn: () => void) {
fn();
}
call(bla.greet) // greet1 undefined
call(bla.greet2) //greet2 me
call(bla.greet3) // greet3 undefined
Run Code Online (Sandbox Code Playgroud)
这在将函数作为事件处理程序传递给另一个组件时尤为重要。
分配功能的地方
类方法(例如greet)在原型上分配,字段初始化(例如greet2和greet3)在构造函数中分配。这意味着greet2并且greet3将有更大的内存占用,因为它们每次Greeter实例化时都需要分配一个新的闭包。
打字稿中 this 的类型是什么。
Typescript 将在方法 ( ) 和箭头函数 ( ) 中输入this为实例,但将输入为 any in 。如果您尝试在下使用,这将导致错误Greetergreetgreet2thisgreet3thisgreet3noImplictAny
何时使用它们
如果此函数不会作为事件处理程序传递给另一个组件,请使用方法语法(除非您使用bind或其他方法来确保this仍然是类的实例)
当您的函数将传递给其他组件并且您需要访问this函数内部时,请使用箭头函数语法。
真的想不出一个好的用例,一般避免。
this 关键词区别:在上面所有三个都相同,this但是当您将方法传递给另一个函数时,您会看到不同之处。
class Greeter {
constructor() {
}
greet() {
console.log(this);
}
greet2 = () => {
console.log(this);
}
greet3 = function() {
console.log(this);
}
}
let bla = new Greeter();
function wrapper(f){
f();
}
wrapper(bla.greet) //undefined
wrapper(bla.greet2) //Greeter
wrapper(bla.greet3) //undefinedRun Code Online (Sandbox Code Playgroud)
但是还有另一个区别,第一种方法是在prototype,class而其他两种不是。它们是对象实例的方法。
class Greeter {
constructor() {
}
greet() {
console.log('greet1', this);
}
greet2 = () => {
console.log('greet2', this);
}
greet3 = function() {
console.log('greet3', this);
}
}
let bla = new Greeter();
console.log(Object.getOwnPropertyNames(Greeter.prototype))Run Code Online (Sandbox Code Playgroud)
如果我在类中 ->
str = "my string";以及我可以说的所有 3 种方法console.log(this.str),它会输出“我的字符串”。但我想知道 - 这真的是同一件事吗
不,它们不是同一回事。正如我提到的那样,greet2并且greet3不会打开,Greeter.prototype而是会在实例本身上。这意味着,如果您创建它们的1000实例,Greeter则会将 1000 个不同的方法(greet2和greet3)存储在内存中,用于 1000 个不同的实例。但是greet所有实例都有一个方法。
请参阅以下带有两个实例的片段 Greeter()
| 归档时间: |
|
| 查看次数: |
441 次 |
| 最近记录: |