在什么JS引擎中,特别是对于LowerCase和toUpperCase的区域设置敏感?

tho*_*rn̈ 21 javascript unicode turkish internationalization angularjs

在一些库的代码中(例如AngularJS,链接指向代码中的特定行),我可以看到使用自定义大小写转换函数而不是标准函数.假设在具有土耳其语语言环境的浏览器中,标准函数不能按预期工作,这是合理的:

console.log("SCRIPT".toLowerCase()); // "scr?pt"
console.log("script".toUpperCase()); // "SCR?PT"
Run Code Online (Sandbox Code Playgroud)

但这是真的还是一直如此?浏览器真的有这样的表现吗?如果是这样,他们中的哪一个呢?node.js怎么样?其他JS引擎?

这些toLocaleLowerCasetoLocaleUpperCase方法的存在意味着toLowerCase并且toUpperCase是区域不变的,不是吗?

对于什么样的浏览器,具体而言,它的角团队保留此检查的代码:if ('i' !== 'I'.toLowerCase())...


如果您的浏览器(设备)使用土耳其语或阿塞拜疆语区域设置,请运行此代码段并在发现问题确实存在时写信给我.

if ('i' !== 'I'.toLowerCase()) {
  document.write('Ooops! toLowerCase is locale-sensitive in your browser. ' +
    'Please write your user-agent in the comments to this question: ' +
    navigator.userAgent); 
} else {
  document.write('toLowerCase isn\'t locale-sensitive in your browser. ' +
    'Everything works as expected!');
}
Run Code Online (Sandbox Code Playgroud)
<html lang="tr">
Run Code Online (Sandbox Code Playgroud)

anu*_*anu 14

遵循ECMA-262 5.1标准的任何JS实现都必须实现String.prototype.toLocaleLowerCaseString.prototype.toLocaleUpperCase

并且根据标准toLocaleLowerCase,应该根据特定于语言环境的映射将字符串转换为小写映射.

在哪里toLowerCase转换为由unicode映射定义的小写字符串.

对于大多数语言而言toLocaleLowerCase,toLowerCase给出相同的结果.但是,对于某些语言,如土耳其的情况下映射不按照Unicode映射因此toLowerCasetoLocaleLowerCase得到不同的结果.

您使用的库/框架(Jquery,Angular,Node等)无论如何都没有任何区别.它是用于运行JS库的JS实现,用于创建和更改内容.

出于所有实际目的,可以准确地得出结论,Node/Angular或任何其他JS库和框架在处理字符串时都表现得完全相同(只要它们被JS Engine用于实现ECMA-262 3及更高版本).话虽如此,我确信很多框架扩展了字符串对象以添加更多功能,但ECMA-262 5.1定义基本属性和功能始终存在且WILL行为完全相同.

要了解更多信息,请访问:http://www.ecma-international.org/ecma-262/5.1/#sec-15.5.4.17

就浏览器而言,所有现代浏览器都在其JS引擎中实现ECMA-262 5.1标准.我不确定Node,但是从我对Node的有限曝光,我认为他们也使用按照ECMA-262 5.1标准实现的JS.

  • 刚刚在我的Chrome中尝试过.它改变了CSS转换案例的方式(`text-transform:uppercase`),但不影响JS. (2认同)

fal*_*lla 13

注意:请注意,我无法测试它!


根据ECMAScript规范:

String.prototype.toLowerCase()

[...]

出于此操作的目的,字符串的16位代码单元被视为Unicode基本多语言平面中的代码点.代理代码点直接从S传输到L而没有任何映射.

必须根据Unicode字符数据库中的大小写映射派生结果(这显然不仅包括UnicodeData.txt文件,包括Unicode 2.1.8及更高版本中随附的SpecialCasings.txt文件).

[...]

String.prototype.toLocaleLowerCase()

此函数与toLowerCase完全相同,不同之处在于其结果旨在为主机环境的当前区域设置生成正确的结果,而不是与区域设置无关的结果.只有少数情况(例如土耳其语)存在差异,其中该语言的规则与常规Unicode案例映射冲突.

[...]

并根据Unicode字符数据库特殊套管:

[...]

格式

此文件中的条目采用以下机器可读格式:

<code>; <lower>; <title>; <upper>; (<condition_list>;)? # <comment>

无条件映射

[...]

用点保留I的规范等价.突厥语在下面处理.

0130; 0069 0307; 0130; 0130; # LATIN CAPITAL LETTER I WITH DOT ABOVE

[...]

语言敏感映射这些字符的完整大小写映射取决于语言,也可能取决于上下文(字符在之前或之后).有关更多信息,请参阅此文件的标头和Unicode标准.

立陶宛

立陶宛语在点缀后以小写字母保留点.

在"i"之后用鞋面或标题删除DOT ABOVE

0307; 0307; ; ; lt After_Soft_Dotted; # COMBINING DOT ABOVE

当上面有更多重音时,在小写大写I和J时,在上面引入一个明确的点.(在立陶宛语中使用的口音:严重,尖锐,波浪形以上和ogonek)

0049; 0069 0307; 0049; 0049; lt More_Above; # LATIN CAPITAL LETTER I

004A; 006A 0307; 004A; 004A; lt More_Above; # LATIN CAPITAL LETTER J

012E; 012F 0307; 012E; 012E; lt More_Above; # LATIN CAPITAL LETTER I WITH OGONEK

00CC; 0069 0307 0300; 00CC; 00CC; lt; # LATIN CAPITAL LETTER I WITH GRAVE

00CD; 0069 0307 0301; 00CD; 00CD; lt; # LATIN CAPITAL LETTER I WITH ACUTE

0128; 0069 0307 0303; 0128; 0128; lt; #LATIN CAPITAL LETTER I WITH TILDE

土耳其和阿塞拜疆

我和我无点; I-dot和i是土耳其语和阿塞拜疆语中的案例对以下规则处理这些案例.

0130; 0069; 0130; 0130; tr; # LATIN CAPITAL LETTER I WITH DOT ABOVE

0130; 0069; 0130; 0130; az; # LATIN CAPITAL LETTER I WITH DOT ABOVE

小写时,删除序列I + dot_above中的dot_above,这将变为i.这与规范等效的I-dot_above的行为相匹配

0307; ; 0307; 0307; tr After_I; # COMBINING DOT ABOVE

0307; ; 0307; 0307; az After_I; # COMBINING DOT ABOVE

当小写时,除非我在dot_above之前,它变成无点的i.

0049; 0131; 0049; 0049; tr Not_Before_Dot; # LATIN CAPITAL LETTER I

0049; 0131; 0049; 0049; az Not_Before_Dot; # LATIN CAPITAL LETTER I

当大写时,我变成了一个虚线的大写我

0069; 0069; 0130; 0130; tr; # LATIN SMALL LETTER I

0069; 0069; 0130; 0130; az; # LATIN SMALL LETTER I

注意:以下情况已在UnicodeData.txt文件中.

0131; 0131; 0049; 0049; tr; # LATIN SMALL LETTER DOTLESS I

EOF

此外,根据绝对初学者的JavaScript (由Terry McNavage提供):

> "I".toLowerCase() // "i"
> "i".toUpperCase() // "I"
> "I".toLocaleLowerCase() // "<dotless-i>"
> "i".toLocaleUpperCase() // "<dotted-I>"
Run Code Online (Sandbox Code Playgroud)

注意:toLocaleLowerCase()根据您的操作系统设置toLocaleUpperCase()转换大小写.您必须将这些设置更改为土耳其语才能使上一个样本生效.或者只是听我的话!

并且根据bobince对转换JavaScript字符串的评论是全部小写?问题:

Accept-Language并且navigator.language是两个完全独立的设置.Accept-Language反映了用户所选择的他们希望在网页中接收哪种语言的偏好(这种设置对于JS来说是不可访问的).navigator.language仅反映Web浏览器的哪些本地化安装,通常不应用于任何事情.这两个值都与系统区域设置无关,系统区域设置决定了toLocaleLowerCase()将执行的操作; 这是浏览器prefs范围之外的操作系统级别设置.


因此,设置lang="tr-TR"html不会反映真实的测试用例,因为它是重现特殊外壳示例所需的操作系统设置.

我认为只有较小的点缀-I或大写无点-i才能在使用toLowerCase()或时特定于语言环境toUpperCase().

根据那些可信/官方消息来源,我认为你是对的:'i' !== 'I'.toLowerCase()总是评价为假.

但是,正如我所说,我无法在这里测试它.

  • @thorn是的,我的回答有理论.但它也有实践!当我指出一些*第三方*经验,如Bobince和Terry(即使那些不是我的)时,他们就是现实.好吧,无论如何,我认为这将是一个很好的贡献. (4认同)