有多种语法用于在javascript对象中嵌入函数,还有多种语法用于类型注释。为了这个问题的目的,我将把它们称为";键入键";(in
-Car1;键入外部键";(out
-Car2,Car4(-请告诉我是否有更好的方式来描述它们。
看看.js
的输出,我只能推断出:
- Typescript在键入和变量赋值之间对
in
和out
的任何组合都不会抛出错误 - 当
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
是指使用的Car1
和Car3
的语法 - "键入外部键";,
out
是指用于Car2
和Car4
的语法
这里有两个问题:
第一个:类型的语法。这两种不同的语法意味着完全相同的东西(请注意,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
。(