对象中函数的多种语法(Typescript)



有多种语法用于在javascript对象中嵌入函数,还有多种语法用于类型注释。为了这个问题的目的,我将把它们称为";键入键";(in-Car1;键入外部键";(out-Car2,Car4(-请告诉我是否有更好的方式来描述它们。

看看.js的输出,我只能推断出:

  • Typescript在键入和变量赋值之间对inout的任何组合都不会抛出错误
  • in语法用于类型和变量声明时,仅保留this上下文
  • 因此CCD_ 8语法必须是";正确的方式";做这件事(???(

使用下面的各种语法组合在对象中嵌入函数之间还有什么区别(如果有的话(?

.ts文件:

interface Car1 {
brand: string;
summary(string): string;
}
interface Car2 {
brand: string;
summary: (string) => string;
}
interface Car3 {
brand: string;
summary(string): string;
}
interface Car4 {
brand: string;
summary: (string) => string;
}
const myFirstCar: Car1 = {
brand: "Tesla",
summary(color: string): string {
return `This car is a ${color} ${this.brand}`;
},
};
const mySecondCar: Car2 = {
brand: "Ferrari",
summary: (color: string) => {
return `This car is a ${color} ${this.brand}`;
},
};
const myThirdCar: Car3 = {
brand: "Porsche",
summary: (color: string) => {
return `This car is a ${color} ${this.brand}`;
},
};
const myFourthCar: Car4 = {
brand: "Ferrari",
summary: (color: string) => {
return `This car is a ${color} ${this.brand}`;
},
};
const color = "red";
console.log(myFirstCar.summary);
console.log(myFirstCar.summary(color));
console.log(mySecondCar.summary);
console.log(mySecondCar.summary(color));
console.log(myThirdCar.summary);
console.log(myThirdCar.summary(color));
console.log(myFourthCar.summary);
console.log(myFourthCar.summary(color));

编译的.js文件:

var _this = this;
var myFirstCar = {
brand: "Tesla",
summary: function (color) {
return "This car is a " + color + " " + this.brand;
}
};
var mySecondCar = {
brand: "Ferrari",
summary: function (color) {
return "This car is a " + color + " " + _this.brand;
}
};
var myThirdCar = {
brand: "Porsche",
summary: function (color) {
return "This car is a " + color + " " + _this.brand;
}
};
var myFourthCar = {
brand: "Ferrari",
summary: function (color) {
return "This car is a " + color + " " + _this.brand;
}
};
var color = "red";
console.log(myFirstCar.summary);
console.log(myFirstCar.summary(color));
console.log(mySecondCar.summary);
console.log(mySecondCar.summary(color));
console.log(myThirdCar.summary);
console.log(myThirdCar.summary(color));
console.log(myFourthCar.summary);
console.log(myFourthCar.summary(color));

控制台输出

[Function: summary]
This car is a red Tesla
[Function: summary]
This car is a red undefined
[Function: summary]
This car is a red undefined
[Function: summarizeCar]

编辑:

  • 对引用的不同语法类型的说明
  • "键入内部键";,in是指使用的Car1Car3的语法
  • "键入外部键";,out是指用于Car2Car4的语法

这里有两个问题:

第一个:类型的语法。这两种不同的语法意味着完全相同的东西(请注意,interface Car1 {summary(string): string;}的语法缺少参数名称(。

那是

interface A {
fun(val: string): string;
}

和完全一样吗

interface A {
fun: (val: string) => string;
}

第二:不同行为的原因是您使用的箭头与正常函数。

当你使用

const myThirdCar: Car3 = {
brand: "Porsche",
summary: (color: string) => {
return `This car is a ${color} ${this.brand}`;
},
};

您正在创建一个箭头函数,其this绑定到周围的上下文,即TypeScript在编译到不支持箭头函数的版本时创建并在这些函数中使用的_this

请注意,在您的示例中,这些函数将使用顶级上下文中的this,在浏览器中为window,在NodeJ下为global,因此人们尽可能避免使用它,因为除非您真正知道自己在做什么,否则很可能会引入错误。

当你做

const myFirstCar: Car1 = {
brand: "Tesla",
summary(color: string): string {
return `This car is a ${color} ${this.brand}`;
},
};

您正在创建一个正则函数,其中this由它的调用方式决定。在这种情况下,因为它是用属性访问(myFirstCar.summary(color)(调用的,所以该函数的this将是.左侧的元素,即myFirstCar

因此,不存在";正确的";这样做的方式。我特别喜欢interface A {method(val:string): string},因为它看起来更自然,但你应该始终如一。

关于对象初始值设定项语法;正确的";方式,这取决于您是否想要箭头与常规函数行为。

从根本上讲,您似乎在问方法语法和用箭头函数初始化的

属性语法方法语法(JavaScript(:

const carA = {
brand: "Tesla",
summary() {
return `This car is a ${this.brand}`;
}
};

使用箭头函数初始化的属性语法:

const carB = {
brand: "Tesla",
summary: () => {
return `This car is a ${this.brand}`;
}
};

为了完整起见,还有第三个:用传统函数初始化的属性语法:

const carC = {
brand: "Tesla",
summary: function() {
return `This car is a ${this.brand}`;
}
};

执行obj.fn()时,如果函数是方法(carA(或传统函数(carC(,则函数调用的this将设置为obj。但是,如果fn是一个箭头函数(carB(,由于箭头函数位于this之上,因此this是创建箭头函数的上下文中的任何内容,对于您的特定示例

,这不是您想要的。这就是为什么上面的carB没有显示品牌:

const carA = {
brand: "Tesla",
summary() {
return `This car is a ${this.brand}`;
}
};
const carB = {
brand: "Tesla",
summary: () => {
return `This car is a ${this.brand}`;
}
};
const carC = {
brand: "Tesla",
summary: function() {
return `This car is a ${this.brand}`;
}
};
console.log("carA:", carA.summary()); // "carA: This car is a Tesla"
console.log("carB:", carB.summary()); // "carB: This car is a undefined"
console.log("carC:", carC.summary()); // "carC: This car is a Tesla"

因此在语法上必须是;正确的方式";做这个(???(

两者都不是"对"这取决于你想要什么。如果您希望函数在创建函数的this绑定上关闭(正如您经常希望的那样(,请使用箭头函数(carB(。如果您希望调用方根据函数的调用方式设置this(您通常希望这样做(,请使用方法语法(carA(或传统函数的属性初始值设定项语法(carC(。

(FWIW:方法语法和传统函数的属性初始值设定项语法之间的区别是:a(方法语法更简洁,B(方法有一个到定义它们的对象的链接,这样它们就可以访问该对象的原型super。传统函数不能使用super。(

最新更新