TypeScript 有两个字符串接口,称为String
和StringConstructor
。
此外,TypeScript语言规范在第 1 章第 1.3 节中提供了此代码示例:
interface JQuery {
text(content: string);
}
interface JQueryStatic {
get(url: string, callback: (data: string) => any);
(query: string): JQuery;
}
JQuery
/JQueryStatic
和String
/StringConstructor
接口和 doStatic
和Constructor
接口相关有什么区别?
编辑:是的,我知道链接的书已经过时了3 年。
我要从 切换String
到RegExp
因为有一个皱纹String
我稍后会提到*。
实例接口(如RegExp
和JQuery
)通常表示可以存在多个不同实例的对象类型。关联的静态接口(如RegExpConstructor
和JQueryStatic
)通常表示创建或返回这些实例的对象类型;并且通常这些静态对象中只有一个存在。所以只有一个RegExpConstructor
物体可以制造很多RegExp
物体,也只有一个JQueryStatic
物体可以制造很多JQuery
物体。
实践中一种常见的混淆来源是值和类型之间的名称冲突。单个静态对象的名称(例如,RegExp
或jQuery
)往往与实例接口的名称相同。但是那个静态对象的类型不是实例接口的类型。因此,在运行时命名的值RegExp
的类型为RegExpConstructor
,而不是RegExp
。并且在运行时命名的值jQuery
的类型是JQueryStatic
,而不是JQuery
。这令人困惑,但可能是最好的,因为它允许您在运行时x instanceof Y
和编译时说出类型x
为Y
.
无论如何,如果存在其行为取决于特定实例的属性或方法,则通常位于实例接口上。如果某些属性或方法的行为不依赖于特定实例,则通常位于静态接口上。
构造器接口是一个静态接口,它专门允许您使用其上的new
运算符来创建新实例。在 TypeScript 中,这类似于函数调用签名,但名称为new
,如下所示:
type F = (x: string) => number[];
type C = new(x: string) => number[];
类型F
表示一个函数,它接受一个string
参数并生成一个number
s数组,而类型C
表示一个构造函数,它接受一个string
参数并生成一个number
s数组:
declare const f: F;
declare const c: C;
const arr1 = f("hey"); // number[]
const oops1 = new f("hey"); // error, f is not newable
const arr2 = new c("hey"); // number[]
const oops2 = c("hey"); // error, c is not callable
有一个静态接口同时也是一个构造器接口是很常见的;所有class
静态接口都是构造函数接口。但并非每个静态接口都是构造函数接口。该JQueryStatic
接口是一个的例子,其是没有的。要从对象中获取JQuery
实例JQueryStatic
,您可以像调用函数一样调用它(这就是(query: string): JQuery;
签名的含义)。
所以这就是JQueryStatic
/JQuery
对和RegExpConstructor
/RegExp
对之间的主要区别,也是问题的主要答案的结尾。
*回到String
皱纹。命名的类型String
特指通过调用构造函数上的运算符构造的对象。还有一个名为(带有小写的 's')的类型,它指的是原始数据类型。实际上,您处理的所有字符串都是 type 的原语,而 a是一个相对不常见的包装对象,它包含一个值。A和 a大多可以互换:new
String
string
string
String
string
string
String
const stringPrimitive = "hello"; // type is string
const stringObject = new String("hello"); // type is String
console.log(stringPrimitive+"!"); // "hello!"
console.log(stringObject+"!"); // "hello!"
console.log(stringPrimitive.charAt(4)); // "o"
console.log(stringObject.charAt(4)); // "o"
除非它们不可互换:
console.log(typeof stringPrimitive); // "string"
console.log(typeof stringObject); // "object"
console.log(stringPrimitive instanceof String); // false
console.log(stringObject instanceof String); // true
当您意识到StringConstructor
也可以像函数一样被调用并生成一个原语 时,情况变得更加混乱string
:
console.log(typeof "hey"); // "string"
console.log(typeof new String("hey")); // "object"
console.log(typeof String("hey")); // "string"
所以这很混乱。这里的规则几乎总是使用string
;从不使用String
. 这就是为什么我将代码示例从String
always-an-object更改为always-an-object RegExp
,对此没有原始数据类型 ( typeof /foo/ === "object"
) 妨碍。
好的,希望有帮助。祝你好运!
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句