问题描述
在一些库的代码中(例如 AngularJS,链接指向代码中的特定行),我可以看到使用自定义大小写转换函数而不是标准函数.假设在具有土耳其语语言环境的浏览器中,标准功能无法按预期工作,这是合理的:
console.log("SCRIPT".toLowerCase());//脚本"console.log("脚本".toUpperCase());//脚本"
但真的如此还是曾经如此?浏览器真的会这样吗?如果是,他们中的哪一个是这样做的?node.js 呢?其他 JS 引擎?
toLocaleLowerCase
和 toLocaleUpperCase
方法的存在意味着 toLowerCase
和 toUpperCase
是语言环境不变的,不是是吗?
特别是对于哪些浏览器,Angular 团队是否在代码中保留了此检查:if ('i' !== 'I'.toLowerCase())...
?
如果您的浏览器(设备)使用土耳其语或阿塞拜疆语言环境,请运行此代码段,如果您发现问题确实存在,请写信给我.
if ('i' !== 'I'.toLowerCase()) {document.write('糟糕!toLowerCase 在你的浏览器中是区域敏感的.' +'请在此问题的评论中写下您的用户代理:' +navigator.userAgent);} 别的 {document.write('toLowerCase 在浏览器中不区分区域设置.' +'一切都按预期进行!');}
注意:请注意,我无法测试!
根据 ECMAScript 规范:>
String.prototype.toLowerCase ( )
[...]
出于此操作的目的,16 位代码单元在 Unicode Basic Multilingual 中,字符串被视为代码点飞机.代理代码点直接从 S 转移到 L没有任何映射.
结果必须根据案例映射中的Unicode 字符数据库(这明确包括不仅UnicodeData.txt 文件,还有 SpecialCasings.txt 文件在 Unicode 2.1.8 及更高版本中伴随它).
[...]
String.prototype.toLocaleLowerCase ( )
这个函数的作用与 toLowerCase 完全一样,只是它的结果旨在为主机产生正确的结果环境的当前语言环境,而不是独立于语言环境的结果.只会在少数情况下有所不同(例如土耳其语)该语言的规则与常规 Unicode 冲突的地方案例映射.
[...]
并且根据 Unicode 字符数据库特殊大小写:
[...]
格式
此文件中的条目采用以下机器可读格式:
;<降低>;<标题>;<上部>;(<condition_list>;)?#
无条件映射
[...]
用点保留 I 的规范等价.突厥语处理下面.
0130;0069 0307;0130;0130;# 带点的拉丁文大写字母 I
[...]
语言敏感映射这些字符的完整大小写映射取决于语言,也许还取决于上下文(哪些字符出现在之前或之后).想要查询更多的信息请参阅此文件的标题和 Unicode 标准.
立陶宛语
立陶宛语后跟重音符号时保留小写 i 中的点.
在带有大写或标题的i"之后删除 DOT ABOVE
0307;0307;;;lt After_Soft_Dotted;# 结合上面的点
在小写大写字母 I 和 J 时在上方引入一个明确的点每当上面有更多的口音时.(立陶宛语使用的重音:grave、acute、tilde above 和 ogonek)
0049;0069 0307;0049;0049;lt More_Above;# 拉丁大写字母 I
004A;006A 0307;004A;004A;lt More_Above;# 拉丁大写字母 J
012E;012F 0307;012E;012E;lt More_Above;# 带有 OGONEK 的拉丁文大写字母 I
00CC;0069 0307 0300;00CC;00CC;lt;# 带坟墓的拉丁文大写字母 I
00CD;0069 0307 0301;00CD;00CD;lt;# 带有 ACUTE 的拉丁大写字母 I
0128;0069 0307 0303;0128;0128;lt;#带波浪号的拉丁大写字母 I
土耳其语和阿塞拜疆语
I 和 i-dotless;I-dot 和 i 是土耳其语和阿塞拜疆语中的大小写对以下规则处理这些情况.
0130;0069;0130;0130;tr;# 带点的拉丁文大写字母 I
0130;0069;0130;0130;az;# 带点的拉丁文大写字母 I
小写时,将序列I + dot_above中的dot_above去掉,变成i.这与规范等效的 I-dot_above 的行为相匹配
0307;;0307;0307;tr After_I;# 结合上面的点
0307;;0307;0307;az After_I;# 结合上面的点
小写时,除非一个 I 在 dot_above 之前,否则它会变成一个无点的 i.
0049;0131;0049;0049;tr Not_Before_Dot;# 拉丁大写字母 I
0049;0131;0049;0049;az Not_Before_Dot;# 拉丁大写字母 I
大写时,i 变成虚线的大写 I
0069;0069;0130;0130;tr;# 拉丁文小写字母 I
0069;0069;0130;0130;az;# 拉丁文小写字母 I
注意:以下情况已经在 UnicodeData.txt 文件中.
0131;0131;0049;0049;tr;# 拉丁小写字母无点 I
EOF
此外,根据 :
>"I".toLowerCase()//"i">"i".toUpperCase()//"我">"I".toLocaleLowerCase()//"">"i".toLocaleUpperCase()//""
注意:toLocaleLowerCase()
和 toLocaleUpperCase()
根据您的操作系统设置转换大小写.您必须将这些设置更改为土耳其语才能使上一个示例正常工作.或者只是相信我的话!
并且根据 bobince 对将 JavaScript 字符串全部转换为小写? 问题的评论:
Accept-Language
和 navigator.language
是两个完全独立的设置.Accept-Language
反映了用户选择的偏好他们希望在网页中接收哪些语言(此设置是不幸的是,JS 无法访问).navigator.language
只是反映安装了哪种本地化的 Web 浏览器,并且应该一般不用于任何事情.这两个值是不相关的到系统区域设置,这是决定什么的位toLocaleLowerCase() 会做;这是操作系统级别的设置超出范围浏览器的首选项.
因此,将 lang="tr-TR"
设置为 html
不会反映真实的测试用例,因为它是重现特殊大小写所需的操作系统设置示例.
我认为在使用 toLowerCase()
或 toUpperCase()
时,只有小写的 dotted-I 或大写的 dotless-i 才是特定于语言环境的.
根据那些可靠/官方消息来源,我认为您是对的:'i' !== 'I'.toLowerCase()
总是会评估为 false.
但是,正如我所说,我无法在这里测试.
In the code of some libraries (e.g. AngularJS, the link leads to the specific lines in the code), I can see that custom case-conversion functions are used instead of the standard ones. It's justified by an assumption that in browsers with Turkish locale, the standard functions don't work as expected:
console.log("SCRIPT".toLowerCase()); // "scrıpt"
console.log("script".toUpperCase()); // "SCRİPT"
But is it really or was it ever the case? Do the browsers really behave this way? If so, which of them do? What about node.js? Other JS engines?
The existance of the toLocaleLowerCase
and toLocaleUpperCase
methods implies that toLowerCase
and toUpperCase
are locale-invariant, doesn't it?
For what browsers, specifically, does the Angular team retain this check in the code: if ('i' !== 'I'.toLowerCase())...
?
If your browser (device) uses the Turkish or Azerbaijan locale, please run this snippet and write me if you discover that the issue indeed exists.
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!');
}
<html lang="tr">
Note: Please, note that I couldn't test it!
As per ECMAScript specification:
And as per Unicode Character Database Special Casing:
Unconditional mappings
[...]
0130; 0069 0307; 0130; 0130; # LATIN CAPITAL LETTER I WITH DOT ABOVE
[...]
Lithuanian
0307; 0307; ; ; lt After_Soft_Dotted; # COMBINING DOT ABOVE
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
Turkish and Azeri
0130; 0069; 0130; 0130; tr; # LATIN CAPITAL LETTER I WITH DOT ABOVE
0130; 0069; 0130; 0130; az; # LATIN CAPITAL LETTER I WITH DOT ABOVE
0307; ; 0307; 0307; tr After_I; # COMBINING DOT ABOVE
0307; ; 0307; 0307; az After_I; # COMBINING DOT ABOVE
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
Also, as per JavaScript for Absolute Beginners (by Terry McNavage):
And as per bobince's comment over Convert JavaScript String to be all lower case? question:
So, setting lang="tr-TR"
to html
won't reflect a real test case, since it's an OS setting that's required to reproduce the special casing example.
I think that only lowercasing dotted-I or uppercasing dotless-i would be locale specific when using toLowerCase()
or toUpperCase()
.
As per those credible/official sources, I think you're right: 'i' !== 'I'.toLowerCase()
would always evaluate to false.
But, as I said, I couldn't test it here.
这篇关于在什么 JS 引擎中,具体来说,是 toLowerCase &toUpperCase 语言环境敏感?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!