Чи JavaScript нетипізована мова?


104

Я виявив, що деякі люди називають JavaScript "динамічно, слабо набраною" мовою, а деякі навіть кажуть "нетипізованою"? Що це насправді?

Відповіді:


133

JavaScript не вводиться:


(джерело: no.gd )

Навіть Брендан Ейх так говорить. У Twitter він відповів на тему, яка пов’язана з цим питанням:

... академічні типи використовують "нетипізовані", щоб означати "немає статичних типів" ...

Тож проблема полягає в тому, що існує кілька різних визначень нетипізованих .

Одне визначення обговорювалося в одному з вищезазначених відповідей - час виконання не позначає значення, а просто розглядає кожне значення як біт. JavaScript має значення тегів і відрізняється поведінкою на основі цих тегів. Тож JavaScript, очевидно, не відповідає цій категорії.

Інше визначення - з теорії мови програмування (академічна річ, на яку посилається Брендан). У цій області Нетипізовані просто означає , що все , що належить до одного типу .

Чому? Оскільки мова буде генерувати програму лише тоді, коли вона зможе довести, що типи вирівнюються (він же - відповідність Curry-Howard ; типи - теореми, програми - докази). Це означає нетипізованою мовою:

  1. Програма буде завжди генерується
  2. Тому типи завжди співпадають
  3. Тому має бути лише один тип

На відміну від введеної мови:

  1. Програма може не генеруватися
  2. Тому що типи можуть не збігатися
  3. Оскільки програма може містити кілька типів

Отже, у PLT, типізований просто означає динамічно набраний, а введений - просто статично набраний . JavaScript напевно не вводиться в цій категорії.

Дивитися також:


6
І звичайно, "ніякі статичні типи" не є такими ж, як "немає оголошень типу".
Андреас Россберг

+1. Можливо, вам слід також зв’язати це у своїй відповіді. Цей "слабо типізований" Bs занадто поширений.
зниклийфактор

2
Теорія мови програмування правильна. Гігантський скріншот невірний.
Alex W

2
Я був радий бачити, що ця відповідь посилається на допис у блозі Гарпера, але було б добре, якби спільнота PLT відмовилася від "нетипізованого" на користь "об'єднаного". Визначення "нетипізованого" значення "просто біти" насправді має сенс. Використовувати "нетипізований" для опису мови, формальна специфікація якої використовує слово "тип", і говорить про те, що вона має сім типів (Undefined, Null, Number, String, Boolean, Symbol, and 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. Ви повинні прочитати це .
зниклийфактор

48

JavaScript введений слабо . Він, звичайно, не "нетиповий", але його слабо типова природа дозволяє отримати велику гнучкість у плані неявних перетворень.

Майте на увазі, що JavaScript також динамічно набирається. Цей метод набору тексту дозволяє зрозуміти, як "набрання качки" .

Для порівняння вважають, що JavaScript не сильно набраний, а також не набраний статично. Іноді розуміння того, що щось не може допомогти тобі краще побачити, що це таке.


2
-1. Ви повинні прочитати це .
зниклийфактор

3
Ця відповідь набагато краща та набагато точніша, ніж відповідь, яка проголосувала вгорі.
Alex W

3
@JimboJonny: Неправильно. Якщо в присутності девайса Асамблеї немає, було б не надто некоректно стверджувати, що кожна мова вводиться. Нетипізований означає, що єдині операції здійснюються безпосередньо під керуванням бітом. Але врахуйте, що у Javascript є методи toString () та parseInt (). Не набирайтеся набагато більше, ніж це.
Суамер

2
@Suamere - Ось цитата з "Javascript: Посібник з визначеннями" від O'Reilly: "Важливою відмінністю JavaScript та таких мов, як Java та C, є те, що JavaScript не вводиться. Це означає, що змінна JavaScript може містити значення будь-якого типу даних, на відміну від змінної Java або C, яка може містити лише той певний тип даних, для якого він оголошений. "
Jimbo Jonny

3
Тож якщо ви купуєте в BS, що якийсь чувак стверджує, що академічні люди навмисно використовують слово "нетипізоване", щоб означати "динамічно набране". Тоді так, 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 використовує тип примусу в деяких випадках, що робить тип неявним, оскільки не потрібно чітко вказувати тип змінних. Він підпадає під слабко набраний текст, тому що, на відміну від деяких мов, які розрізняють float та integer тощо, він просто використовує один numberтип, щоб охопити всі числа, і використовує згаданий раніше примус [Розділ 9 Spec ECMAScript] , сильно протиставляючи сильно набрана мова, яка мала б дуже конкретні типи даних (тобто вам потрібно було б вказати intабо float).

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

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


Це не помилка, але питання контексту, дивіться stackoverflow.com/questions/9154388/…
Андреас Россберг,

@AndreasRossberg Це абсолютно є неправильним. Те, на що ви посилаєтесь, у своєму безсоромно популяризованому посиланні - це система типів. Причина, що термін є неправильним, полягає в тому, що це неоднозначно. Більшість програмістів вважають, що тип даних не вводиться системою, коли вони чують про нетипізовану мову . Я думаю , що коментар Конрада Рудофа насправді сприяє цьому.
Alex W

Не впевнений, чому ви вважаєте безсоромним посилатися на мою попередню відповідь, а не повторювати її тут. Також я чітко сказав, що контекст має значення. На відміну від скарги К. Рудольфа, у літературі є цілком послідовні та широко прийняті визначення поняття "тип системи", і я її цитував. Звичайно, ви можете знайти їх заплутаними у вашому контексті, але це не робить їх "неправильними".
Андреас Россберг

@AndreasRossberg Контекст тут дуже важливий. Відповідь у верхній частині голосування говорить про "нетипізований = відсутність оголошень типу", що явно невірно. Що я говорю, це неправильне значення в цьому контексті. Тут ніхто не згадував обчислення лямбда, і робити це є дещо вибагливим у цьому простому випадку.
Alex W

1

Пам'ятайте, що JavaScript дозволяє запитувати, що таке typeof(your_variable), і порівнювати типи: 5==="5"return false. Тому я не думаю, що ви можете це назвати нетиповим.

Він динамічно і (оцінюється як) слабо набраний. Ви можете знати, що він використовує Duck typeping (див. Посилання andrew) і пропонує OOP, хоча прототипування замість класів та успадкування.


Введення змінної не має нічого спільного з кастингом значень. Це стосується оголошень типів для змінних. У Javascript взагалі немає конструкції для цього, через що так мало javascripters навіть розуміє цю концепцію, і чому так багато з них неправильно трактує введення змінної як щось спільне з порівнянням або кастингом змінних типів. У JS ви не можете оголосити String a = "blah";або var a:String = 'blah';(тобто вводити змінні) НА ВСІ. Ось чому це не типово.
Jimbo Jonny

0

Поки він набраний (ви можете запитати "typeof someVar" і дізнатися його конкретний тип, він дуже слабкий).

Подано:

  var a = "5";

Ви можете сказати, що a - це рядок. Однак якщо ви напишете:

  var b = a + 10;

b - int, рівний 15, тому діяв так само, як int. Звичайно, ви можете написати:

  var c = a + "Hello World";

і c буде дорівнювати "5Hello World", тому a знову діє як струна.


1) Закидання значення! = Введення змінної 2) воно не слабке, воно не існує. Ви не можете вводити змінну в JavaScript.
Jimbo Jonny

Цікаво, чому ця відповідь отримала два голоси. Визначення, яке я знайшов при слабкому введенні тексту, говорить саме так: Тип значення визначається на основі способу його використання.
aioobe

Хоча це точно? Я отримую bрівні 510: ideone.com/BRcSW7
aioobe
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.