我发现有些人称 JavaScript 为“动态、弱类型”的语言,但有些人甚至说“无类型”?哪个是真的?
JavaScript 是一种无类型语言吗?
JavaScript是无类型的:
(来源:no.gd)
甚至 Brendan Eich 也这么说。在 Twitter 上,他回复了与此问题相关的线程:
所以问题是untyped有几个不同的定义。
在上述答案之一中已经讨论了一个定义 - 运行时不标记值,只是将每个值视为位。JavaScript会标记值并根据这些标记具有不同的行为。所以 JavaScript 显然不适合这个类别。
另一个定义来自编程语言理论(Brendan 所指的学术内容)。在这个领域,无类型只是意味着一切都属于单一类型。
为什么?因为一种语言只有在可以证明类型对齐时才会生成程序(又名Curry-Howard 对应关系;类型是定理,程序是证明)。这意味着在无类型语言中:
- 总是生成一个程序
- 因此类型总是匹配
- 因此必须只有一种类型
与类型化语言相反:
- 可能不会生成程序
- 因为类型可能不匹配
- 因为一个程序可以包含多种类型
所以你去了,在 PLT 中,无类型只是意味着动态类型,类型只是意味着静态类型。JavaScript 在此类别中绝对是无类型的。
也可以看看:
强/弱 可以被认为与编译器如何处理类型有关(如果适用)。
弱类型意味着编译器(如果适用)不会强制执行正确的类型。如果没有隐式编译器插入,指令将在运行时出错。
"12345" * 1 === 12345 // string * number => number
强类型意味着有一个编译器,它需要你从string到integer的显式转换。
(int) "12345" * 1 === 12345
在任何一种情况下,某些编译器的功能都可以在编译时隐式更改指令,以便为您进行转换,前提是它可以确定这是正确的做法。
到目前为止,JavaScript 可以归类为非强类型。这要么意味着它是弱类型的或非类型的。
动态/静态 可以被认为与语言指令如何操作类型有关。
动态类型意味着强制执行值的类型,但变量仅表示任何类型的任何值。
x = 12345; // number x = "string"; // string x = { key: "value" }; // object y = 123 + x; // error or implicit conversion must take place.
静态类型意味着变量类型是强强制的,而值类型是不那么强制的。
int x = 12345; // binds x to the type int x = "string"; // too late, x is an integer - error string y = 123; // error or implicit conversion must take place.
到目前为止,JavaScript 可以归类为非静态类型。此外,它似乎是动态类型的,如果有输入的话。所以我们需要看看打字是什么意思。
Typed意味着语言区分不同的类型,例如string、 number、 boolean、 object、 array、 null、 undefined等。此外,每个操作都绑定到特定类型。因此,您不能将整数除以字符串。
2 / "blah" // produces NaN
无类型的装置分割的操作整数由串将导致在治疗的头四个字节的字符串作为整数。这是因为无类型操作直接在位上进行,没有要观察的类型。结果将是非常出乎意料的:
2 / "blah" // will be treated as 2 / 1500275048
由于 JavaScript 根据类型化的定义运行,因此必须如此。因此它必须是动态类型和弱类型的。
如果有人声称 JavaScript 是无类型的,那只是为了学术理论,而不是为了实际应用。
在作者看来,JavaScript 也被归类为Dynamically typed。Wiki 指出动态类型语言在运行时而不是在编译器中进行类型检查,而弱类型是指在代码中动态更改类型的能力。所以是的,它既是动态类型又是弱类型。
这里让很多程序员感到困惑的问题是,像这样的定义在某处没有标准化。术语无类型编程语言是模棱两可的。那是指没有数据类型的语言还是 lambda 演算无类型变体的语言?
JavaScript/ECMAScript 有一个类型系统,它的所有函数域都可以接受任何引用规范类型。所以这意味着 JavaScript 实际上只有一种数据类型。这是一个对非常高级的 JavaScript 程序员来说更重要的实现问题。一般的 JavaScript 程序员只关心ECMAScript 已经指定的抽象 语言数据类型。
在日常程序员的上下文中,而不是研究人员或理论计算机科学家,术语无类型是用词不当,因为大多数人不做 lambda 演算。因此,这个术语混淆了大众,似乎在声明 JavaScript 没有任何数据类型,这根本不是真的。任何使用过的人都typeof
知道 JavaScript 有自己的语言数据类型:
var test = "this is text";
typeof(test);
产量
“string”
ECMAScript 为语言定义了以下类型:undefined
, null
, string
, boolean
, number
,object
http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
对 JavaScript 更准确的指定是隐式类型化、动态类型化或弱/松散类型化(或它们的某种组合),因为 JavaScript在某些情况下使用类型强制,这使得类型隐式,因为您不必显式指定你的变量类型。它属于弱类型,因为与一些区分浮点数和整数等的语言不同,它只使用一种number
类型来包含所有数字,并使用前面提到的类型强制转换[ECMAScript Spec 的第 9 节],与 a具有非常特定数据类型的强类型语言(即您必须指定int
或float
)。
静态和动态类型语言的定义没有标准化,但是当计算机开始发展时,字节的大小也没有标准化。静态和动态类型通常是指某些语言功能的存在。其中之一是在运行时进行类型检查,或称为动态类型检查。如果您使用过 JavaScript,您就会知道它肯定会等到运行时才检查类型,这就是您TypeError
在代码执行期间遇到异常的原因。示例在这里
我认为最高投票的答案是将JavaScript 函数的多态性与实际上可以接受任何东西(如 Lambda 微积分的无类型变体)的函数混淆,这是一种关联谬误。