弱类型语言、ASCII与Unicode、非相等运算符
弱类型语言和强类型语言
- 强类型和弱类型主要是根据变量类型处理的角度来分类的;
- 强类型不允许隐式变量类型转换,如Java;
- 弱类型则允许隐式变量类型转换(就是它自己悄悄咪咪会把你的数据类型转换掉,还不报错,真是可气!!),如javascript、php;
ASCII与Unicode的区别
1、位bit(比特),缩写为b,用来表示二进制位,它是计算机内部数据储存的最小单位;
2、字节Byte(拜特),缩写为B,它是计算机数据处理的基本单位;
1Byte = 8bit,1字节等于8位
一、ASCII码
- 计算机内部,所有信息最终都是一个二进制值,8个二进制位可以组合出256种状态,所以一个字节一共可以用来表示256种不同的状态,每一个状态都对应一个符号,也就是256个符号,从
00000000
到11111111
; - 所以在上个世纪60年代,美国制定了一套字符编码,对英语字符与二进制位之间的关系,做了统一规定。这被称为 ASCII 码,一直沿用至今。
- ASCII 码一共规定了128个字符的编码(包含32个不能打印出来的控制符号),比如空格SPACE是32(二进制00100000),大写A是65(二进制01000001),且只占用了一个字节的最后7位,最前面的一位统一规定为0。
二、非ASCII编码
- 英语用128个符号编码就够了,但是用来表示其他语言,128个符号是不够的。比如,在法语中,字母上方有注音符号,它就无法用 ASCII 码表示。于是,一些欧洲国家就决定,利用字节中闲置的最高位编入新的符号。比如,法语中的é的编码为130(二进制10000010)。这样一来,这些欧洲国家使用的编码体系,可以表示最多256个符号。
- 但是对于其他国家,不同的国家有不同的字母,哪怕它们都使用256个符号的编码方式,代表的字母却不一样,所以亟需需要一种全世界通用的编码,这时,Unicode就出来了;
三、Unicode
- 正如上面所说,世界上存在多种编码方式,即使是同一个二进制数字也有可能被解析成不同的符号。所以,当我们打开一个文件时,必须清楚它的编码格式,否则用错误的编码打开,那么它就会出现乱码。为什么电子邮件常常会出现乱码,就是因为发件人和收件人所用的编码格式不一致。
- Unicode是一个很大的符号集合,现在的规模可以容纳100多万个符号,每个符号的编码都不一样。具体的Unicode对应符号,可以查询网站。
四、Unicode的问题
- Unicode只是一个符号集,它只规定了每个符号对应的二进制代码,但却没有规定它该如何在计算机内储存;
- 比如,汉字严的 Unicode 是十六进制数4E25,转换成二进制数足足有15位(100111000100101),就说明它需要2个字节来表示。还有一些更加复杂的符号,可能需要3个或4个字节来表示;
- 这里就有两个严重的问题,第一个问题是,如何才能区别 Unicode 和 ASCII ?计算机怎么知道三个字节表示一个符号,而不是分别表示三个符号呢?第二个问题是,我们已经知道,英文字母只用一个字节表示就够了,如果 Unicode 统一规定,每个符号用三个或四个字节表示,那么每个英文字母前都必然有二到三个字节是0,这对于存储来说是极大的浪费,文本文件的大小会因此大出二三倍,这是无法接受的;
- 所以这时,急需一种统一的编码方式;
五、UTF-8
-
UTF-8 就是在互联网上使用最广的一种 Unicode 的实现方式。其他的编码方式还包括UTF-16(字符用两个字节或四个字节表示)和 UTF-32(字符用四个字节表示),不过在互联网上基本不用。
-
UTF-8可以根据不同的符号而变化字节长度,它的编码规则是:
UTF-8.png
①对于单字节的符号,字节的第一位设为0,后面7位为这个符号的 Unicode 码。因此对于英语字母,UTF-8 编码和 ASCII 码是相同的。
②对于n字节的符号(n > 1),第一个字节的前n位都设为1,第n + 1位设为0(所以有就是说如果大于1个字节,那么就看第一个字节上有几个1,有几个1就说明它有几个字节),后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的 Unicode 码。可以看下图,字母x表示可用编码的位:
-
根据上表,解读 UTF-8 编码非常简单。如果一个字节的第一位是0,则这个字节单独就是一个字符;如果第一位是1,则连续有多少个1,就表示当前字符占用多少个字节。
-
还是以汉字严为例,演示如何实现 UTF-8 编码:
严的 Unicode 是4E25(100111000100101),根据上表,可以发现4E25处在第三行的范围内(0000 0800 - 0000 FFFF),因此严的 UTF-8 编码需要三个字节,即格式是1110xxxx 10xxxxxx 10xxxxxx。然后,从严的最后一个二进制位开始,依次从后向前填入格式中的x,多出的位补0。这样就得到了,严的 UTF-8 编码是11100100 10111000 10100101,转换成十六进制就是E4B8A5
非相等运算符
对于非相等运算符(
>
、<
、>=
、<=
)的算法,先比较两者是否都是字符串,若都是字符串,就按照Unicode码点一个字符一个字符来比较;若都不是,则先将它两都转成数值,再比较数值大小;
1、字符串的比较
- 字符串按照字典顺序进行比较;
- JavaScript 引擎内部首先比较首字符的 Unicode 码点。如果相等,再比较第二个字符的 Unicode 码点,以此类推。
'cat' > 'Cat' // true'
2、非字符串的比较
- 如果两个运算子之间,至少有一个不是字符串,则需要分为以下两种情况:
(1)简单类型
如果两个运算子都是简单类型的值,则是先转成数值再比较
5 > '4' // true
// 等同于 5 > Number('4')
// 即 5 > 4
true > false // true
// 等同于 Number(true) > Number(false)
// 即 1 > 0
2 > true // true
// 等同于 2 > Number(true)
// 即 2 > 1
这里需要注意与NaN的比较。任何值(包括NaN本身)与NaN使用非相等运算符进行比较,返回的都是false。
1 > NaN // false
1 <= NaN // false
'1' > NaN // false
'1' <= NaN // false
NaN > NaN // false
NaN <= NaN // false
(2)对象
如果运算子是对象,会转为原始类型的值,再进行比较