学习日记 (2020-09-02)
学习地址:https://wangdoc.com/javascript/basic/grammar.html#switch-%E7%BB%93%E6%9E%84
1、变量提升。
JavaScript 引擎的工作方式是,先解析代码,获取所有被声明的变量,然后再一行一行地运行。这造成的结果,就是所有的变量的声明语句,都会被提升到代码的头部,这就叫做变量提升(hoisting)。
console.error(a) var a= 1 //相当于 var a; console.error(a) a = 1
2、JavaScript 语言允许,语句的前面有标签(label),相当于定位符,用于跳转到程序的任意位置,标签的格式如下。
label(可以是任意的合法标识符):
语句
top:
for (var i = 0; i < 3; i++){
for (var j = 0; j < 3; j++){
if (i === 1 && j === 1) break top;
console.log('i=' + i + ', j=' + j);
}
}
// i=0, j=0
// i=0, j=1
// i=0, j=2
// i=1, j=0
//,满足条件时,直接跳出双层循环。如果break语句后面不使用标签,则只能跳出内层循环,进入下一次的外层循环。
//标签也可以用于跳出代码块。
foo: {
console.log(1);
break foo;
console.log('本行不会输出');
}
console.log(2);
// 1
// 2
//continue
语句也可以与标签配合使用
top:
for (var i = 0; i < 3; i++){
for (var j = 0; j < 3; j++){
if (i === 1 && j === 1) continue top;
console.log('i=' + i + ', j=' + j);
}
}
// i=0, j=0
// i=0, j=1
// i=0, j=2
// i=1, j=0
// i=2, j=0
// i=2, j=1
// i=2, j=2
JavaScript 有三种方法,可以确定一个值到底是什么类型。
typeof
运算符 可以返回一个值的数据类型instanceof
运算符Object.prototype.toString
方法
// instanceof运算符可以区分数组和对象 var o = {} var a = [] o instanceof Array //false a instanceof Array //true
null
是一个表示“空”的对象,转为数值时为0
;undefined
是一个表示"此处无定义"的原始值,转为数值时为NaN
// undefined null false 0 NaN ""或''(空字符串) if ('') { console.log('true'); } // 没有任何输出 //空数组([])和空对象({})对应的布尔值,都是true if ([]) { console.log('true'); } // true
JavaScript 内部,所有数字都是以64位浮点数形式储存,即使整数也是如此。所以,1
与1.0
是相同的,是同一个数。由于浮点数不是精确的值,所以涉及小数的比较和运算要特别小心。
0.1 + 0.2 === 0.3 // false 0.3 / 0.1 // 2.9999999999999996 (0.3 - 0.2) === (0.2 - 0.1) // false
数值:https://wangdoc.com/javascript/types/number.html#%E6%95%B0%E5%80%BC%E7%B2%BE%E5%BA%A6
字符串:
//报错 var x = 'a b c' //反斜杠的后面必须是换行符,而不能有其他字符(比如空格),否则会报错 var x = 'a\ b\ c'
转义:
\0
:null(\u0000
)\b
:后退键(\u0008
)\f
:换页符(\u000C
)\n
:换行符(\u000A
)\r
:回车键(\u000D
)\t
:制表符(\u0009
)\v
:垂直制表符(\u000B
)\'
:单引号(\u0027
)\"
:双引号(\u0022
)\\
:反斜杠(\u005C )
反斜杠后面紧跟三个八进制数(000
到377
),代表一个字符。HHH
对应该字符的 Unicode 码点,比如\251
表示版权符号。显然,这种方法只能输出256种字符
\x
后面紧跟两个十六进制数(00
到FF
),代表一个字符。HH
对应该字符的 Unicode 码点,比如\xA9
表示版权符号。这种方法也只能输出256种字符。
\u
后面紧跟四个十六进制数(0000
到FFFF
),代表一个字符。XXXX
对应该字符的 Unicode 码点,比如\u00A9
表示版权符号。
'\251' // "©" '\xA9' // "©" '\u00A9' // "©" '\172' === 'z' // true '\x7A' === 'z' // true '\u007A' === 'z' // true //如果在非特殊字符前面使用反斜杠,则反斜杠会被省略。 '\a' // "a
var s = 'hello'; s[0] // "h" s[1] // "e" s[4] // "o" // 直接对字符串使用方括号运算符 'hello'[1] // "e"
//字符串内部的单个字符无法改变和增删,这些操作会默默地失败
var s = 'hello'
delete s[0]
s // 'hello'
s[1]= 'a'
s // 'hello'
JavaScript 引擎内部,所有字符都用 Unicode 表示。JavaScript 不仅以 Unicode 储存字符,还允许直接在程序中使用 Unicode 码点表示字符,即将字符写成\uxxxx
的形式,其中xxxx
代表该字符的 Unicode 码点。比如,\u00A9
代表版权符号
var s = '\u00A9'; s // "©" var f\u006F\u006F = 'abc'; foo // "abc"
我们还需要知道,每个字符在 JavaScript 内部都是以16位(即2个字节)的 UTF-16 格式储存。也就是说,JavaScript 的单位字符长度固定为16位长度,即2个字节。
但是,UTF-16 有两种长度:对于码点在U+0000
到U+FFFF
之间的字符,长度为16位(即2个字节);对于码点在U+10000
到U+10FFFF
之间的字符,长度为32位(即4个字节),而且前两个字节在0xD800
到0xDBFF
之间,后两个字节在0xDC00
到0xDFFF
之间。举例来说,码点U+1D306
对应的字符为𝌆,
它写成 UTF-16 就是0xD834 0xD
F06
。
JavaScript 对 UTF-16 的支持是不完整的,由于历史原因,只支持两字节的字符,不支持四字节的字符。这是因为 JavaScript 第一版发布的时候,Unicode 的码点只编到U+FFFF
,因此两字节足够表示了。后来,Unicode 纳入的字符越来越多,出现了四字节的编码。但是,JavaScript 的标准此时已经定型了,统一将字符长度限制在两字节,导致无法识别四字节的字符。上一节的那个四字节字符𝌆
,浏览器会正确识别这是一个字符,但是 JavaScript 无法识别,会认为这是两个字符。
'𝌆'.length // 2
上面代码中,JavaScript 认为𝌆
的长度为2,而不是1。
总结一下,对于码点在U+10000
到U+10FFFF
之间的字符,JavaScript 总是认为它们是两个字符(length
属性为2)。所以处理的时候,必须把这一点考虑在内,也就是说,JavaScript 返回的字符串长度可能是不正确的。
有时,文本里面包含一些不可打印的符号,比如 ASCII 码0到31的符号都无法打印出来,这时可以使用 Base64 编码,将它们转成可以打印的字符。另一个场景是,有时需要以文本格式传递二进制数据,那么也可以使用 Base64 编码。
所谓 Base64 就是一种编码方法,可以将任意值转成 0~9、A~Z、a-z、+
和/
这64个字符组成的可打印字符。使用它的主要目的,不是为了加密,而是为了不出现特殊字符,简化程序的处理。
JavaScript 原生提供两个 Base64 相关的方法。
btoa()
:任意值转为 Base64 编码atob()
:Base64 编码转为原来的值
var string = 'Hello World!';
btoa(string) // "SGVsbG8gV29ybGQh"
atob('SGVsbG8gV29ybGQh') // "Hello World!"
注意,这两个方法不适合非 ASCII 码的字符,会报错。
btoa('你好') // 报错
要将非 ASCII 码字符转为 Base64 编码,必须中间插入一个转码环节,再使用这两个方法。
function b64Encode(str) {
return btoa(encodeURIComponent(str));
}
function b64Decode(str) {
return decodeURIComponent(atob(str));
}
b64Encode('你好') // "JUU0JUJEJUEwJUU1JUE1JUJE"
b64Decode('JUU0JUJEJUEwJUU1JUE1JUJE') // "你好"