Pull to refresh

Comments 52

Ну дык во всех интерпретируемых языках со слабой типизацией такие финты ушами могут стоить долгих часов отладки ))
Тут дело не в слабой типизации. Тут дело в референсах/указателям.
Это не оператор сравнения, это сравнение строкового литерала со строкой и сравнение двух строк между собой. Это не одно и то же.
Это я к тому, что тут надо программисту понимать, как работает яваскрипт, ничего подводного в этом нет. Точно так же нельзя сравнивать в лоб две переменные-массива. Открываем Фленагана и прямо в первых главках это всё отлично описано.

Тут недавно товарищ для себя и хабра тег legend открывал, эта статья получается откуда-то оттуда же. Грамотный Javascript-программист обязан знать такие вещи.
Проблема в том, что на этом аспекте практически во всех книгах внимание не акцентируется. Про массив всем более-менее всё очевидно, поскольку это всегда объект. Но строки-то бывают не только примитивными типами, но ещё и объектами (хоть и редко). Результатом практически всех встроенных объектов является примитивный тип, поэтому практически всегда никаких проблем не возникает. Но если кто-то напишет функцию, возвращающую именно объект, то проблема становится актуальной.

А статья как раз таки и адресована не грамотным программистам, а, скорее, начинающим. В javascript создаётся иллюзия понятности, отчасти авторами дурных книг; и человек прочитав всякое, начинает мнить себя спецом. Вот именно этой аудитории и адресован текст.
Хм, наерное, я слишком строго смотрю на вещи. Новичкам это действительно будет полезно, хотя на практике на эти грабли напарываются, наверное, на первом же скрипте, работающим со строками.
Вот именно на этом точно не напарываются, потому что практическе всегда результаты всех встроенных операций/методов/функций возвращают примитивные типы везде, где это возможно.
а в java со строками ещё веселее…
String a = «world»;
String b = «world»;
a=«hello»;
print(b); // результат «hello»;
:)
Наверное, имелось в виду

String b = a;
При String b = a; // результат тоже будет world
Не совсем понимаю, что вы хотите показать в Java, но то, что привели вы — неправильно. Результат конечно же будет «world». Объект String в Java immutable (неизменяем), поэтому при изменении a — создаются новые объекты и а начинает указывать на новый объект. String b не изменится и при таком коде String a = «world»; String b = a; a = «hello»;…

Как помнится мне, в Java String особенность только в том, что JVM может применять String constant pool. И тогда появляется различие в String a = «a»; и String a = new String(«a»); В первом варианте строковая константа сначала ищется в пуле, если ее там нет, то объект создается и помещается в пул.
Поэтому при неправильном сравнении строк (не используя equals) возникает JVM зависимая фича:
String a = «a»;
String b = «a»; // a == b TRUE
String b = new String(«a»); // a == b FALSE
String a = new String(«a»); // a == b FALSE
Можно проще. Во втором случае сравнение двух объектов между собой.
Разные экземпляры класса всегда будут отличаться при таком сравнении. Не копал глубоко в Javascript, но тут явно нужно сравнивать значение toString()
Угу, но если значение приезжает из функции, например, из какого-то чужого модуля, можно серьёзно наколоться на сравнении.
Нужно просто к этому привыкнуть, в любом языке есть парочка «подводных камней», которые со временем могут оказаться даже полезными.
> С точки зрения программиста примитивное значение типа string и объект, созданный из строки конструктором String(), практически неотличимы

С точки зрения КАКОГО програмимиста? Который не умеет отличать ссылочные типы от типов значений?
Этот пример разбирается практически в любой книге по программированию.
Вы удивитесь, как много javascript-программистов не знают разницы между a=String(«abc») и a=new String(«abc»). А уж о прототипной сущности языка вообще единицы знают :).
Почему эти люди называют себя Javascript-программистами?
Это терминологический вопрос. Не медаль же давать за знание спеков языка. Лично меня не коробит, пусть как угодно себя называют.
Медаль — не медаль, но знать теоретическую сторону технологии — для профессионального владения ею — нужно обязательно.

Кстати, попутно спрошу всех. Будет ли интересно разобрать некоторые тонкости ECMA? Почему спрашиваю: я обычно не пишу статьи, но, на форумах, порой, (кто желает углубиться в JS) спрашивают о теоретических тонкостях JS (Variable object, Scope chain, различия Function declaration от Function expression и т.д.). Каждый раз писать одно и то же — тоже не хочется, как правило, кидаются ссылки на предыдущие ответы. Но так получается, вырвано из контекста и далеко не всегда усваивается. Вот я и думаю, собрать на одном блоге (а, может, и здесь) некоторый терминологическо-теоретический справочник по данным аспектам.

Какой процент интересуется JS глубоко? Есть ли необходимость в этом?
UFO just landed and posted this here
Необходимость есть, конечно же пишите.
Присоединюсь, и могу сказать, что людей которым это было бы полезно на порядки больше тех, кто отметился в этих комментариях.
Необходимость есть. Будто сам не знаешь. ;)
Ну, насчет необходимости, я имел в виду больше интерес — интересен ли сам JS в глубоком понимании, или многим достаточно выучить лишь некий фреймворк ;) Zeroglif, если что — поможешь мне поправками и дополнениями :)

Ок, всем спасибо, в скором времени постараюсь выложить некоторый материал из наиболее часто спрашиваемых областей ECMAscript'a. Скорей всего, это будет напоминать справочную информацию (чтобы, в случае последующих аналогичных вопросов, ссылаться на эти описания, а не на отрывки из ответов с форумов); стилистику подачи постараюсь сделать как можно более доступную (не строго-теоретико-сухую, как в стандарте), но, всё-таки, не спускаться до кухонно-разговорного языка, т.к. это, всё же, будут не статьи для новичков, и нужно будет иметь уже хоть какую-нибудь теоретическую базу в JS. Но, конечно, всё можно будет уточнить в комментариях.
Я интересуюсь. Между тем, кто интересуется, тот и помочь сможет в организации знаний.
Да, конечно, помощь в знаниях всегда приветствуется.
Чтобы зарабатывать деньги, продавая своё незнание :)
Потому что другие называют себя к примеру «верстальщик» или «веб-программист». А сами даже спецификацию толком не читали.

Я вот тоже задался вопросом почему тут habrahabr.ru/blogs/webdev/62556/ и меня тут же заминусовали. Что делать, леммингов тут значительно больше.
Программиисты? Тогда я врач, т.к. знаю, как пластырь лепить. И каскадер, т.к. кувыркаться умею.
Ну вас-то на работу ни в больницу, ни в кино не возьмут, а тех ребят в ЛамерСофт возьмут. Потому они и имеют формальное право называться программистами.
В данном примере не совсем очевидно где кончается «примитиный» тип значений и где начинается ссыслчный.
В Java тоже есть подобные подводные камни:

Integer i1 = 100;
Integer i2 = 100;
Integer i3 = 1000;
Integer i4 = 1000;
System.out.println(i1==i2);
System.out.println(i3==i4);

выведет true false, так как значения [-128;127] сравниваются по значению, остальные — по ссылке.
Двумя понятными словами это очень сложно сказать. Определения из ECMA-262 весьма точны, но для быстрого понимания не очень годятся.

Примитивный — это, например, значение строкового литерала, или результат выполнения большинства функций, возвращающих строки. Ссылочный тип начинается там, где слово new встречается. Но это так, на пальцах. В общем случае это неверно.
объектные строки скорее так появляются:

jQuery(['1',2]).each(function(){ alert( typeof this ) })
Это все потому, что есть целых два оператора сравнения — «value equality operator» и «object equality operator». Если это написать большим красным маркером на стене, то все сразу становится хорошо и удобно :).
Тогда уж obj1.valueOf() === obj2.valueOf()
А сами то пробовали? ;) Вот вам лог небольшой:
>>> a = 'str';
«str»
>>> b = new String(a)
str
>>> c = new String(a)
str
>>> b === c
false
UFO just landed and posted this here
Нет, да и, наверное, в нём нет особого смысл. При желании, впрочем, можно легко реализовать и прицепить на вершину прототипной иерархии.
Перегрузка стандартных операторов рулит :)
Javascript программист самый симпатичный :)
UFO just landed and posted this here
Капитан Очевидность промолчит про метод equals, который есть первый выучиваемый программистами на Джаве (и люто бешено ненавидимый С++-никами которые на ней вынуждены писать).
UFO just landed and posted this here
UFO just landed and posted this here
Практически во всех языках можно найти примеры, когда == не транзитивно.
Например, в C++, C#, Java и многих других:

    int a = 1000000000;
    float b = 1000000000;
    int c = 1000000001;
    print(a == b); // true
    print(b == c); // true
    print(a == c); // false    

Sign up to leave a comment.

Articles