Ответ 1
Два источника, которые вы цитируете, спецификация языка и Crockford "JavaScript: Хорошие детали" (стр. 103) говорят то же самое, хотя последний говорит это гораздо более кратко (и, очевидно, если вы уже знаете предмет). Для справки я приведу Крокфорда:
JavaScript был разработан в то время, когда Unicode должен был иметь не более 65 536 символов. С тех пор он вырос до 1 миллиона символов.
Знаки JavaScript - 16 бит. Этого достаточно, чтобы покрыть оригинал 65 536 (который теперь известен как базовый многоязычный самолет). Каждый из оставшихся миллионов символов может быть представлен как пара символов. Unicode считает пару единственным символом. JavaScript считает, что пара представляет собой два разных символа.
Спецификация языка называет 16-битный блок "символом" и "блоком кода". С другой стороны, символ "Юникод" или "кодовая точка" может (в редких случаях) нуждаться в двух 16-битных "кодовых единицах", которые должны быть представлены.
Все свойства и методы строки JavaScript, такие как length
, substr()
и т.д., работают с 16-разрядными "символами" (было бы очень неэффективно работать с 16-битными/32-разрядными символами Unicode, т.е. символы UTF-16). Например, это означает, что если вы не будете осторожны, с substr()
вы можете оставить одну половину только 32-битного символа Unicode UTF-16. JavaScript не будет жаловаться, пока вы его не отобразите, и, возможно, даже не пожалуется, если вы это сделаете. Это связано с тем, что, как указано в спецификации, JavaScript не проверяет правильность символов UTF-16, он предполагает, что они есть.
В своем вопросе вы спрашиваете
Выполняет ли [ Node.js] UTF-8 все возможные кодовые точки правильно или не так?
Поскольку все возможные кодовые точки UTF-8 преобразуются в UTF-16 (как один или два 16-разрядных "символа" ) во входном сигнале до того, как что-либо еще происходит, и наоборот, на выходе, ответ зависит от того, что вы подразумеваете под "правильно", но если вы принимаете JavaScript-интерпретацию этого "правильно", ответ "да".