对象中的函数的多种语法(打字稿)

时间:2020-08-14 13:38:08

标签: typescript

在JavaScript对象中嵌入函数有多种语法,对于类型注释也有多种语法。出于这个问题的目的,我将它们称为“键入密钥”(in-Car1,Car3)和“键入外部密钥”(out-Car2,Car4)-请让我知道是否有更好的方法来描述它们。

看一看.js的输出,我得出的结论是:

  • 对于打字和变量分配之间的inout的任何组合,Typescript均不会引发错误。
  • this语法用于 类型和变量声明时,
  • in上下文仅保留 >
  • 因此,in语法必须是这样做的“正确方法”(???)

使用以下各种语法组合在对象中嵌入函数之间还有其他区别吗?

.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的语法

2 个答案:

答案 0 :(得分:2)

这里有两个问题:

第一:类型的语法。两种不同的语法含义完全相同(请注意,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 < / p>

因此,没有做到这一点的“正确”方法。我特别喜欢interface A {method(val:string): string},因为它看起来更自然,但您应该保持一致。

关于对象初始值设定项语法,也没有“正确”的方法,这取决于您是否想要箭头还是常规函数的行为。

答案 1 :(得分:1)

从根本上说,您似乎要问的是方法语法和用箭头函数初始化的属性语法之间的区别。

方法语法(在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将设置为{{1} }进行函数调用。但是,如果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)或属性初始化程序语法({ {1}}。

(FWIW:方法语法与传统函数的属性初始化程序语法之间的区别是:A)方法语法更加简洁,B)方法具有指向定义对象的链接,以便它们可以访问carA,该对象的原型。传统函数不能使用carC。)