JavaScript 是一种非类型化语言吗?

我发现有些人称 JavaScript 为“动态的、弱类型的”语言,但有些人甚至说“非类型的”?到底是什么?

71764 次浏览

JavaScript 是 弱打字。它当然不是“无类型的”,但它的弱类型特性允许在隐式转换方面有很大的灵活性。

请记住,JavaScript 也是动态类型化的。这种类型化方法允许使用 “鸭子打字”

作为比较,考虑到 JavaScript 不是 strongly typed也不是 statically typed.有时了解什么东西 不是可以帮助你更好地看到它是什么。

按照作者的观点,JavaScript 也被归类为 动态类型。Wiki 声明动态类型语言在运行时而不是在编译器中进行类型检查,而弱类型是指在代码中动态更改类型的能力。因此,是的,它既是动态类型的,也是弱类型的。

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

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

    "12345" * 1 === 12345  // string * number => number
    

    强类型 意味着存在一个编译器,它希望将 绳子显式转换为 整数

    (int) "12345" * 1 === 12345
    

    In either case, some compiler's features can implicitly alter the instruction during compile-time to do conversions for you, if it can determine that is the right thing to do.

    到目前为止,JavaScript 可以归类为非强类型(Not-strong-Type) ,这意味着它要么是弱类型的,要么是非类型的。

动态/静态 可以与语言指令如何操纵类型有关。

  • Dynamically typed means the 价值's type is enforced, but the variable simply represents any value of any type.

    x = 12345;    // number
    x = "string"; // string
    x = { key: "value" }; // object
    y = 123 + x; // error or implicit conversion must take place.
    

    Statically typed means the 变量 type is strongly enforced, and the value type is less-so enforced.

    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 可以归类为非静态类型。此外,它似乎是动态类型,如果有类型。所以我们需要知道打字是什么意思。

类型 意味着语言区分不同类型,如 绳子number布尔型object数组无效未定义等。此外,每个操作都绑定到特定类型。所以你不能把 整数除以 绳子

    2 / "blah"  // produces NaN

非类型化 意味着将 整数除以 string的操作将导致将 string的前4个字节视为 整数。这是因为非类型化操作直接发生在位上,没有要观察的类型。结果将是意想不到的:

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

由于 JavaScript 的行为是根据被类型化的定义进行的,因此它必须是。因此它必须是动态类型的,而且是弱类型的。

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

While it is typed (you can ask "typeof someVar" and learn its specific type, it's very weak.

给出:

  var a = "5";

你可以说 a 是一个字符串,但是,如果你写:

  var b = a + 10;

B 是一个等于15的整型数,所以 a 就像一个整型数。当然,你可以这样写:

  var c = a + "Hello World";

C 将等于“5Hello World”,所以 a 再次表现为字符串。

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

It is dynamically and (estimated as) weakly typed. 您可能想知道它使用 Duck 类型(参见 Andrew 的链接) ,并通过 原型机提供 OOP,而不是类和继承。

无类型化的 JavaScript :


(资料来源: 不,天啊)

就连 Brendan Eich 也这么说。在 Twitter 上,他回复了一条与这个问题相关的帖子:

... 学术类型用“无类型”来表示“没有静态类型”..。

所以问题是 untyped有几个不同的定义。

在上面的一个答案中已经讨论了一个定义——运行时不标记值,只是将每个值作为位处理。JavaScript是的标记值,并且基于这些标记具有不同的行为。因此,JavaScript 显然不属于这一类。

The other definition is from Programming Language Theory (the academic thing that Brendan is referring to). In this domain, 无法打印 just means 所有东西都属于同一种类型.

为什么?因为语言只有在能够证明类型对齐时才会生成程序(也称为 柯里-霍华德同构; 类型是定理,程序是证明)。在一种非类型化的语言中,这意味着:

  1. 程序是由 一直都是生成的
  2. 因此,类型 一直都是匹配
  3. 因此,必须只有 类型

与打字语言相反:

  1. 生成程序 也许不会
  2. 因为 也许不会类型匹配
  3. 因为程序可以包含 多个类型

就是这样,在 PLT 中,无法打印表示 dynamically typed打好了表示 静态输入。JavaScript 在这个类别中肯定是无类型的。

参见:

这里令许多程序员感到困惑的问题是,这样的定义在某些地方并没有标准化。非类型化编程语言这个术语是模棱两可的。这是指一种没有 data types的语言,还是指一种 lambda 演算 untyped variant的语言?

JavaScript/ECMAScript 有一个 打字系统,它的所有函数的域都将接受任何 Reference 规范类型。这意味着 JavaScript 实际上只有一种数据类型。这是一个实现问题,对于非常高级的 JavaScript 程序员来说更为重要。一般的 JavaScript 程序员只关心 ECMAScript 指定的 摘要language data types

在日常的程序员,而不是研究人员或理论计算机科学家的背景下,术语 无法打印是一个错误的名称,因为大多数人不做 lambda 微积分。因此,这个术语混淆了大众,似乎宣称 JavaScript 没有任何数据类型,而事实并非如此。任何使用过 typeof的人都知道 JavaScript 有自己的语言数据类型:

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

产量

“字符串”

ECMAScript defines 以下八种语言类型: Undefined, Null, Boolean, String, Symbol, Number, BigInt, and Object.

JavaScript 更准确的名称应该是隐式类型、动态类型或弱/松散类型(或者其他组合) ,因为 JavaScript 在某些情况下使用 类型胁迫类型胁迫,这使得类型隐式化,因为您不必显式地指定变量的类型。它属于弱类型语言,因为不像有些语言区分浮点数和整数等,它只使用一个 number类型来包含所有数字,并使用类型强制前面提到的 < a href = “ http://www.ecma-international. org/publications/files/ECMA-ST/Ecma-262.pdf”rel = “ nofollow noReferrer”> [ Section 9 of ECMAScript Spec ] ,与强类型语言有很强的对比,强类型语言将有非常特定的数据类型(即你必须指定 intfloat)。

静态和动态类型语言的定义没有标准化,但是在计算机开始发展时,字节的大小也没有标准化。静态类型和动态类型通常指的是某些语言特性的存在。其中一个是 运行时的类型检查,或者叫做 动态类型检查动态类型检查。如果您使用过 JavaScript,那么您已经知道它肯定会等到运行时才检查类型,这就是为什么在代码执行期间会出现 TypeError异常的原因。举个例子

我认为最受欢迎的答案是将 JavaScript 函数的多态性与可以接受任何字面意思的函数混淆(就像 Lambda 微积分的非类型化变体一样) ,后者是 罪恶关联

松散类型的 JS 的另一个有趣的例子:

Log (typeof (typeof (5)))

结果是字符串。为什么?因为初始类型的结果是整数,它本身就是一个字符串。我假设在强类型语言中,不会出现这种类型的更改。也许我错了,但这是我第一次开始明白疯狂的 JS 可以是哈哈大笑

我认为 JavaScript 是强类型和动态类型的。

但是,这取决于一系列术语,似乎是松散的定义,所以以上是真实的,只有当你接受下面的定义..。

强/弱

  • “强”类型可以防止用于一种数据类型的操作在另一种类型上执行。例如,尝试写入数组的 N这个元素,其中对象不是数组。为了内存安全,需要强类型。
  • “弱”是强的反义词。

静态/动态

  • “静态”输入在程序执行之前检查类型(在编译/传输时)。这需要将类型信息编码到语言的语法中。
  • “动态”是静态的反义词。

JavaScript 不会让您损坏内存(因此是“强内存”) ,而是在运行时执行所有的检查和类型转换/强制(因此是“动态的”)。


我发现将“强对弱”看作与“静态对动态”正交是有帮助的。有些语言是强和静态的(例如没有 unsafe上下文的 C #) ,强和动态的(大多数“脚本”语言似乎都属于这一类) ,弱和静态的(C/C + +)。

不知道什么是弱和动态... 汇编程序,也许:)