Является ли JavaScript нетипизированным языком?

104

Я обнаружил, что некоторые люди называют JavaScript «динамически, слабо типизированным» языком, а некоторые даже говорят «нетипизированным»? Что это на самом деле?

Дениз Доган
источник

Ответы:

133

JavaScript является нетипизированным:


(источник: no.gd )

Так говорит даже Брендан Эйх. В Твиттере он ответил на тему, связанную с этим вопросом:

... академические типы используют "нетипизированный" для обозначения "не статических типов" ...

Проблема в том, что существует несколько разных определений нетипизированного .

В одном из приведенных выше ответов говорилось об одном определении - среда выполнения не маркирует значения, а просто обрабатывает каждое значение как биты. JavaScript делает значения тегов и имеет разное поведение в зависимости от этих тегов. Так что JavaScript явно не подходит под эту категорию.

Другое определение взято из теории языков программирования (академическая вещь, о которой говорит Брендан). В этом домене нетипизированный означает, что все принадлежит одному типу .

Зачем? Потому что язык будет генерировать программу только тогда, когда он сможет доказать, что типы совпадают (также известное как соответствие Карри-Ховарда ; типы - теоремы, программы - доказательства). На нетипизированном языке это означает:

  1. Программа всегда генерируется
  2. Поэтому типы всегда совпадают
  3. Следовательно, должен быть только один тип

В отличие от типизированного языка:

  1. Программа не может быть создана
  2. Потому что типы могут не совпадать
  3. Поскольку программа может содержать несколько типов

Итак, в PLT нетипизированный означает просто динамически типизированный, а типизированный - просто статический . JavaScript определенно не относится к этой категории.

Смотрите также:

Брайан МакКенна
источник
6
И, конечно же, «отсутствие статических типов» - это не то же самое, что «отсутствие объявлений типа».
Андреас Россберг
+1. Возможно, вам также следует указать это в своем ответе. Этот "слабо типизированный" БС слишком распространен.
missingfaktor
2
Теория языка программирования верна. Гигантский скриншот неверен.
Alex W
2
Я был рад видеть, что этот ответ ссылается на сообщение в блоге Харпера, но было бы хорошо, если бы сообщество PLT отказалось от «нетипизированного» в пользу «единого». Определение «нетипизированного», означающего «просто биты», действительно имеет смысл. Использование слова «нетипизированный» для описания языка, формальная спецификация которого использует слово «тип» и говорит, что он имеет семь типов (Undefined, Null, Number, String, Boolean, Symbol и Object), действительно сбивает с толку. Большинство людей не хотят отделять это понятие типа от определения PLT.
Ray Toal
4
Ваш 1. 2. 3.для нетипизированного языка не соответствует JavaScript. Существует не только один тип - их около 4-5. Итак, как это показывает, что JavaScript нетипизирован?
Дон Чидл,
82

Сильный / слабый можно рассматривать в связи с тем, как компилятор, если применимо, обрабатывает типизацию.

  • Слабо типизированный означает, что компилятор, если применимо, не обеспечивает правильную типизацию. Без неявного вмешательства компилятора инструкция выдаст ошибку во время выполнения.

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

    Строго типизированный означает, что есть компилятор, и он хочет, чтобы вы явно преобразовали строку в целое число .

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

    В любом случае некоторые функции компилятора могут неявно изменять инструкцию во время компиляции, чтобы выполнять преобразования за вас, если он может определить, что это правильно.

    Пока что JavaScript можно отнести к категории несильно типизированных. Это либо означает, что он слабо типизирован или не типизирован.

Динамический / статический можно рассматривать в связи с тем, как языковые инструкции манипулируют типами.

  • Динамически набрано означаетчто значение типа «s это вынужденное, но переменные просто любое значение любого типа.

    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 , undefined и т. Д. Также каждая операция привязана к определенным типам. Таким образом, вы не можете разделить целое число на строку .

    2 / "blah"  // produces NaN

Нетипизированный означает, что операция деления целого числа на строку приведет к обработке первых четырех байтов строки как целого числа . Это связано с тем, что нетипизированные операции выполняются непосредственно с битами, нет типов для наблюдения. Результат будет довольно неожиданным:

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

Поскольку JavaScript ведет себя в соответствии с определением «Типизированный», он должен быть таким. И поэтому он должен быть динамически типизирован и слабо типизирован.

Если кто-то утверждает, что JavaScript является нетипизированным, то это просто для академической теории, а не для практического применения.

Гамбо
источник
1
Но я думаю, что в последнем утверждении есть противоречие. В JavaScript результат деления целочисленной строки четко определен для любого значения целого числа или строки. Это просто не очень полезно!
Дениз Доган
Если у вас есть лучшее определение / описание, не стесняйтесь редактировать его. Вот почему я сделал это вики сообщества.
Gumbo
@skurpur: Вы полностью поменяли значения динамической и слабой печати - исправили.
Рене Саарсу,
Ой, извините, вы редактировали его, пока я редактировал его, и я перезаписал ваши изменения.
Рене Саарсу
3
-1. Вы должны прочитать это .
missingfaktor
48

JavaScript слабо типизирован . Он определенно не является «нетипизированным», но его слабо типизированный характер обеспечивает большую гибкость с точки зрения неявных преобразований.

Имейте в виду, что JavaScript также динамически типизируется. Этот метод набора текста позволяет так называемый «утиный ввод» .

Для сравнения учтите, что JavaScript не является строго типизированным и статически типизированным. Иногда понимание того, чем что-то не является, может помочь вам лучше понять, что это такое.

Эндрю Хэйр
источник
2
-1. Вы должны прочитать это .
missingfaktor
4
Этот ответ намного лучше и точнее, чем ответ, получивший наибольшее количество голосов.
Alex W
3
@JimboJonny: Неправильно. Если не будет разработчика на ассемблере, было бы неправильно утверждать, что каждый язык является типизированным. Нетипизированный означает, что единственные операции относятся непосредственно к манипуляции с битами. Но учтите, что в Javascript есть методы toString () и parseInt (). Не набирайте больше, чем это.
Suamere
2
@Suamere - Вот цитата из «Javascript: The Definitive Guide» от O'Reilly: «Важное различие между JavaScript и такими языками, как Java и C, состоит в том, что JavaScript не типизирован. Отчасти это означает, что переменная JavaScript может содержать значение любого типа данных, в отличие от переменных Java или C, которые могут содержать только один конкретный тип данных, для которых она объявлена ​​».
Джимбо Джонни
3
Так что, если вы согласны с тем, что какой-то чувак утверждает, что ученые намеренно используют слово «нетипизированный» для обозначения «динамически типизированный». Тогда да, JavaScript не типизирован всеми вашими доказательствами. Но если вы знаете, что «нетипизированный» неправильно используется для представления языков, которые действительно «динамически типизированы», тогда просто назовите эти чертовы языки «динамически типизированными». tinyurl.com/czhcv54
Suamere
8

По мнению автора, JavaScript также относится к категории динамически типизированных . Wiki утверждает, что языки с динамической типизацией проверяются типом во время выполнения, а не в компиляторе, в то время как слабая типизация относится к возможности изменять тип на лету в вашем коде. Так что да, это как динамически типизировано, так и слабо типизировано.

Даррен Ньютон
источник
6

Проблема, которая сбивает с толку многих программистов, заключается в том, что подобные определения где-то не стандартизированы. Термин « нетипизированный язык программирования» неоднозначен. Относится ли это к языку, у которого нет типов данных, или к языку, который является нетипизированным вариантом лямбда-исчисления ?

JavaScript / ECMAScript имеет систему типов, и все домены его функций принимают любой ссылочный тип спецификации. Это означает, что в действительности JavaScript имеет единственный тип данных. Это вопрос реализации, который более важен для очень продвинутых программистов JavaScript. Среднестатистического программиста JavaScript интересуют только типы данных абстрактного языка , указанные в ECMAScript.

В контексте обычного программиста, а не исследователя или ученого-теоретика, термин « нетипизированный» - неправильное употребление, потому что большинство людей не используют лямбда-исчисления. Таким образом, этот термин сбивает с толку и, кажется, заявляет, что JavaScript не имеет никаких типов данных, что просто неверно. Любой, кто когда-либо использовал, typeofзнает, что у JavaScript есть свои типы данных языка:

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

дает

"строка"

ECMAScript определяет следующие типы для языка: undefined, null, string, boolean, number,object

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

Более точное обозначение для JavaScript было бы неявно типизированным, динамически типизированным или слабо / слабо типизированным (или некоторой их комбинацией), в этом JavaScript в некоторых случаях используется приведение типа, что делает тип неявным, поскольку вам не нужно явно указывать тип тип ваших переменных. Он подпадает под слабо типизированный, потому что, в отличие от некоторых языков, которые различают числа с плавающей запятой, целочисленные и т. Д., Он просто использует один numberтип, охватывающий все числа, и использует приведение типов, упомянутое ранее [Раздел 9 спецификации ECMAScript] , что сильно контрастирует с строго типизированный язык, который будет иметь очень специфические типы данных (т.е. вам нужно будет указать intили float).

Определения языков со статической и динамической типизацией не стандартизированы, однако не был и размер байта, когда компьютеры только начинали развиваться. Статическая и динамическая типизация чаще всего подразумевает наличие определенных языковых функций. Одна из них - проверка типов во время выполнения или так называемая динамическая проверка типов . Если вы использовали JavaScript, вы уже знаете, что он определенно ждет, пока среда выполнения проверяет типы, поэтому вы получаете TypeErrorисключения во время выполнения вашего кода. Пример здесь

Я думаю, что получивший наибольшее количество голосов ответ путает полиморфизм функций JavaScript с функциями, которые принимают буквально все (как с нетипизированными вариантами лямбда-исчисления), что является ошибкой ассоциации .

Алекс В
источник
Это не неправильное название, но контекст имеет значение, см. Stackoverflow.com/questions/9154388/…
Андреас Россберг
@AndreasRossberg Это абсолютно является неправильным. В своей бессовестно саморекламируемой ссылке вы имеете в виду систему типов. Причина, по которой этот термин используется неправильно, состоит в том, что он неоднозначен. Большинство программистов думают, что тип данных, а не система типов, когда слышат о нетипизированном языке . Я думаю, что комментарий Конрада Рудофа действительно убедил меня в этом.
Alex W
Не уверен, почему вы считаете «бессовестным» сослаться на мой предыдущий ответ вместо того, чтобы повторять его здесь. Кроме того, я четко сказал, что контекст имеет значение. В отличие от жалобы К. Рудольфа, в литературе есть совершенно последовательные и широко признанные определения «системы типов», и я процитировал одно из них. Конечно, вы можете найти их сбивающими с толку в вашем контексте, но это не делает их неправильными.
Андреас Россберг
@AndreasRossberg Контекст здесь очень важен. В ответе, получившем наибольшее количество голосов, говорится, что «untyped = нет объявлений типа», что явно неверно. Я говорю о том, что в данном контексте это неправильно. Никто не упомянул здесь лямбда-исчисление, и в этом простом случае это несколько претенциозно.
Alex W
1

Помните, что JavaScript позволяет вам спрашивать, что такое typeof(your_variable), и сравнивать типы: 5==="5"возвращает false. Поэтому я не думаю, что это можно назвать нетипизированным.

Он динамически и (оценивается как) слабо типизирован. Возможно, вы захотите узнать, что он использует утиную типизацию (см. Ссылку Эндрю) и предлагает ООП через прототипирование вместо классов и наследования.

пример меня
источник
Ввод переменной не имеет ничего общего с приведением значений. Это связано с объявлениями типов для переменных. В Javascript вообще нет конструкции для этого, поэтому так мало javascripters понимают эту концепцию и почему многие из них неверно истолковывают типизацию переменных как что-то связанное со сравнением или приведением типов переменных. В JS вы не можете объявить String a = "blah";или var a:String = 'blah';(т.е. типизированные переменные) ВООБЩЕ. Вот почему он не типизирован.
Джимбо Джонни
0

Пока он набран (вы можете спросить "typeof someVar" и узнать его конкретный тип, он очень слабый.

Дано:

  var a = "5";

можно сказать, что a - это строка. Однако если вы затем напишете:

  var b = a + 10;

b - это int, равное 15, поэтому a действует так же, как int. Конечно, вы можете написать:

  var c = a + "Hello World";

и c будет равно "5Hello World", поэтому a снова действует как строка.

Джеймс Карран
источник
1) Приведение значения! = Ввод переменной 2) он неслабый, его не существует. Вы не можете ввести переменную в javascript.
Джимбо Джонни
Любопытно, почему этот ответ получил два голоса против. Определение, которое я нашел для слабой типизации, говорит именно следующее: тип значения определяется в зависимости от того, как оно используется.
aioobe 07
Это правда? Я получаю bравные 510: ideone.com/BRcSW7
aioobe 07