JavaScript是非类型化语言吗?


Answers:


133

JavaScript 未输入类型:


(来源:no.gd

甚至布伦丹·艾希(Brendan Eich)也是这样。在Twitter上,他回复了一个与此问题相关的话题:

学术类型使用“无类型”来表示“无静态类型”

因此,问题在于未类型化有几种不同的定义

在上面的答案之一中已经讨论了一个定义-运行时不标记值,而只是将每个值视为位。JavaScript 标记值,并基于这些标记具有不同的行为。因此,JavaScript显然不适合此类。

另一个定义来自编程语言理论(Brendan所指的学术东西)。在此域中,无类型只是意味着所有内容都属于一种类型

为什么?因为一种语言只有在可以证明类型对齐时才会生成程序(又名Curry-Howard对应;类型是定理,程序是证明)。这意味着使用非类型化语言:

  1. 程序总是生成
  2. 因此类型总是匹配的
  3. 因此只能有一种类型

与输入语言相反:

  1. 可能未生成程序
  2. 因为类型可能不匹配
  3. 因为程序可以包含多种类型

所以你去,在PLT,类型化只是手段动态类型类型化只是手段静态类型。在此类别中,JavaScript绝对是没有类型的。

也可以看看:


6
当然,“无静态类型”与“无类型声明”也不相同。
安德烈亚斯·罗斯伯格

+1。您也许还应该在答案中将此链接起来。这种“弱类型” bs太普遍了。
missingfaktor,2012年

2
编程语言理论是正确的。巨型屏幕截图不正确。
Alex W

2
我很高兴看到此答案引用了Harper的博客文章,但是如果PLT社区放弃“ untyped”而改为“ unityped”,那将是很好的。实际上,“无类型”的定义意味着“只是位”。用“无类型”来描述一种语言,其形式规范使用“类型”一词并说它有七种类型(未定义,空值,数字,字符串,布尔值,符号和对象),这确实令人困惑。大多数人不希望将这种类型的概念与PLT def区别开。
Ray Toal

4
你的 1. 2. 3.的非键入语言与JavaScript不匹配。没有只有一个类型-大约有4 - 5。那么,如何演示JavaScript是无类型?
Don Cheadle

82

可以考虑强/弱与编译器(如果适用)如何处理类型有关。

  • 弱类型意味着编译器(如果适用)不会强制执行正确的类型。没有隐式的编译器插入,指令将在运行时出错。

    "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可以归类为非静态类型。另外,如果完全键入,它似乎是动态键入的。因此,我们需要了解“打字”的含义。

类型化是指该语言区分不同类型,例如字符串数字布尔值对象数组 null未定义等等。同样,每个操作都绑定到特定类型。因此您不能将整数除以字符串

    2 / "blah"  // produces NaN

无类型的装置分割的操作整数将导致在治疗的头四个字节的字符串作为整数。这是因为未类型化操作直接发生在位上,没有类型可观察。结果将是非常出乎意料的:

    2 / "blah"  // will be treated as  2 / 1500275048

由于JavaScript会根据“类型化”的定义来运行,因此必须如此。因此,它必须是动态类型的和弱类型的。

如果有人声称JavaScript是无类型的,那只是出于学术理论,而不是实际应用。


1
但我认为上一句话有矛盾之处。在JavaScript中,对于整数或字符串的任何值,整数字符串除法的结果都是明确定义的。只是不是很有用!
Deniz Dogan

如果您有更好的定义/说明,请随时对其进行编辑。这就是为什么我使它成为社区Wiki。
Gumbo

@skurpur:您已经完全交换了动态和弱类型的含义-更正了这一点。
Rene Saarsoo,2009年

哦,对不起,您编辑了它,但是我也正在编辑它,而我却覆盖了您的更改。
Rene Saarsoo,2009年

3
-1。您需要阅读此内容
missingfaktor,2012年

48

JavaScript的类型很弱。它肯定不是“无类型的”,但其弱类型的性质在隐式转换方面具有很大的灵活性。

请记住,JavaScript也是动态输入的。这种键入方法允许所谓的“鸭子键入”

为了进行比较,请考虑不是强类型的 JavaScript 还是静态类型的 JavaScript 有时了解什么不是什么可以帮助您更好地了解它是什么。


2
-1。您需要阅读此内容
missingfaktor,2012年

3
这个答案比最受投票的答案更好,更准确。
Alex W

3
@JimboJonny:不正确。除非有Assembly开发人员在场,否则可以肯定地说每种语言都是正确的。无类型意味着唯一的操作是直接在位操作上。但是请考虑Javascript具有toString()和parseInt()方法。没有比这更多的打字了。
Suamere 2015年

2
@Suamere-这是来自O'Reilly的“ Javascript:权威指南”的引文:“ JavaScript与Java和C之类的语言之间的重要区别是JavaScript是无类型的。从某种意义上讲,这意味着JavaScript变量可以保存任何数据类型的值,而Java或C变量则只能保存声明其数据的一种特定类型的数据。
Jimbo Jonny 2015年

3
因此,如果您购买BS,则有些家伙声称学术人员故意使用“未键入”一词来表示“动态键入”。然后,是的,您的所有证明都无法键入JavaScript。但是,如果您知道“未类型化”被错误地用于表示真正“动态类型化”的语言,则只需将当当语言称为“动态类型化”。tinyurl.com/czhcv54
Suamere 2015年

8

就作者而言,JavaScript也被归类为动态类型。Wiki指出,动态类型化语言在运行时而不是在编译器中进行类型检查,而弱类型是指在代码中即时更改类型的能力。所以是的,它既是动态类型又是弱类型。


6

这里使很多程序员感到困惑的问题是,这样的定义在某些地方没有标准化。术语无类型编程语言是不明确的。这是指没有数据类型的语言还是lambda演算的语言无类型变体吗?

JavaScript / ECMAScript具有类型系统,并且其所有功能的域都将接受任何参考规范类型。因此,实际上意味着JavaScript具有单一数据类型。这是一个实现问题,对于非常高级的JavaScript程序员而言,这更重要。一般的JavaScript程序员只关心抽象 ECMAScript指定语言数据类型

在日常程序员(而不是研究人员或理论计算机科学家)的背景下,“ 无类型 ”一词用词不当,因为大多数人都没有进行lambda演算。因此,该术语使群众感到困惑,并且似乎在宣告JavaScript没有任何数据类型,这是不正确的。任何曾经使用过的人都typeof知道JavaScript具有自己的语言数据类型:

var test = "this is text";
typeof(test);

产量

“串”

ECMAScript中定义了语言以下几种类型:undefinednullstringbooleannumberobject

http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf

对JavaScript而言,更准确的名称是隐式键入,动态类型或弱/松散类型(或其某种组合),因为JavaScript 在某些情况下使用类型强制,这会使类型隐式化,因为您不必显式指定您的变量类型。它属于弱类型,因为与某些区分浮点数和整数等的语言不同,它仅使用一种number类型来包含所有数字,并且利用了前面提到的类型强制(《 ECMAScript Spec第9节》),与a具有非常特殊的数据类型的强类型语言(即,您必须指定intfloat)。

静态和动态类型语言的定义尚未标准化,但是计算机开始发展时的字节大小也没有标准化。静态和动态类型通常是指某些语言功能的存在。其中之一是在运行时进行类型检查,或者称为动态类型检查。如果您使用过JavaScript,则已经知道它肯定会等到运行时检查类型,这就是为什么TypeError在执行代码时会得到异常的原因。这里的例子

我认为投票最多的答案是将JavaScript函数的多态性与可以接受任何字面意义的函数(例如Lambda Calculus的无类型变体)混淆,这就是关联谬误


这不是一个用词不当,但背景事项,请参阅stackoverflow.com/questions/9154388/...
安德烈亚斯Rossberg

@AndreasRossberg绝对个误称。在无耻地自我提升的链接中,您所指的是类型系统。该术语使用不当是因为它含糊不清。大多数程序员在听说无类型语言时都认为数据类型不是类型系统。我认为Konrad Rudoph的评论确实将这一点推向了现实
Alex W

不知道为什么您会发现它无耻地引用了我以前的答案,而不是在这里重复。另外,我明确指出背景很重要。与鲁道夫(K. Rudolph)的抱怨相反,文学中对“类型系统”有完全一致且被广泛接受的定义,我引用其中一个。当然,您可以随意在上下文中发现它们令人困惑,但这并不会使它们成为“错误的名词”。
Andreas Rossberg 2014年

@AndreasRossberg上下文在这里非常重要。投票最多的答案是“未类型化=没有类型声明”,这显然是错误的。我的意思是,在这种情况下,这是一个误称。没有人在这里提到过lambda演算,在这种简单情况下,这样做有点自命不凡。
Alex W

1

请记住,JavaScript允许您询问什么是typeof(your_variable),并比较类型:5==="5"return false。因此,我认为您不能称其为无类型。

它是动态的(估计为)弱类型。您可能想知道它使用Duck键入(请参阅andrew的链接),并通过原型提供OOP,而不是类和继承。


键入变量与值的铸造无关。它与变量类型的声明有关。JavaScript根本没有针对此的构造,这就是为什么这么少的javascripter甚至不理解这个概念的原因,以及为什么这么多javascripter将变量类型误认为与比较或强制转换变量类型有关的原因。在JS中,您完全不能声明String a = "blah";var a:String = 'blah';(即键入变量)。这就是为什么它没有类型。
Jimbo Jonny 2012年

0

键入时(您可以询问“ typeof someVar”并了解其特定类型,但它非常弱。

鉴于:

  var a = "5";

您可能会说a是一个字符串。但是,如果您再写:

  var b = a + 10;

b是一个等于15的int,因此a的行为就像int一样。当然,您可以这样写:

  var c = a + "Hello World";

并且c等于“ 5Hello World”,因此a再次像字符串一样工作。


1)强制转换值!=键入变量2)它不弱,不存在。您无法在javascript中输入变量。
Jimbo Jonny 2012年

很好奇为什么这个答案得了两票。我在弱类型中找到的定义恰好说明了这一点:值的类型取决于其使用方式。
aioobe

这是准确的吗?我b等于510ideone.com/BRcSW7
aioobe
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.