《你不知道的JavaScript(中)》读书摘要

125 阅读4分钟

undefined是一个内置标识符(除非被重新定义,见前面的介绍),它的值为undefined,通过void运算符即可得到该值。

image.png

JavaScript中的数组是通过数字索引的一组任意类型的值。字符串和数组类似,但是它们的行为特征不同,在将字符作为数组来处理时需要特别小心。JavaScript中的数字包括“整数”和“浮点型”。

基本类型中定义了几个特殊的值。

null类型只有一个值null, undefined类型也只有一个值undefined。所有变量在赋值之前默认值都是undefined。 void运算符返回undefined。数字类型有几个特殊值,包括NaN(意指“not a number”,更确切地说是“invalid number”)、+Infinity、-Infinity和-0。

简单标量基本类型值(字符串和数字等)通过值复制来赋值/传递,而复合值(对象等)通过引用复制来赋值/传递。JavaScript中的引用和其他语言中的引用/指针不同,它们不能指向别的变量/引用,只能指向值。

封装对象(object wrapper)扮演着十分重要的角色。由于基本类型值没有.length和.toString()这样的属性和方法,需要通过封装对象才能访问,此时JavaScript会自动为基本类型值包装(box或者wrap)一个封装对象:

image.png

JSON.stringify(..)在对象中遇到undefined、function和symbol时会自动将其忽略,在数组中则会返回null(以保证单元位置不变)

对包含循环引用的对象执行JSON.stringify(..)会出错。如果对象中定义了toJSON()方法,JSON字符串化时会首先调用该方法,然后用它的返回值来进行序列化。如果要对含有非法JSON值的对象做字符串化,或者对象中的某些值无法被序列化时,就需要定义toJSON()方法来返回一个安全的JSON值。

toJSON()应该“返回一个能够被字符串化的安全的JSON值”,而不是“返回一个JSON字符串”。

&&和||运算符的返回值并不一定是布尔类型,而是两个操作数其中一个的值。

image.png

||和&&首先会对第一个操作数(a和c)执行条件判断,如果其不是布尔值(如上例)就先进行ToBoolean强制类型转换,然后再执行条件判断。

对于||来说,如果条件判断结果为true就返回第一个操作数(a和c)的值,如果为false就返回第二个操作数(b)的值。

&&则相反,如果条件判断结果为true就返回第二个操作数(b)的值,如果为false就返回第一个操作数(a和c)的值。

||和&&返回它们其中一个操作数的值,而非条件判断的结果(其中可能涉及强制类型转换)。c && b中c为null,是一个假值,因此&&表达式的结果是null(即c的值),而非条件判断的结果false

image.png

这里a && (b || c)的结果实际上是"foo"而非true,然后再由if将foo强制类型转换为布尔值,所以最后结果为true。 image.png

宽松相等(loose equals)==和严格相等(strict equals)===都用来判断两个值是否“相等”,但是它们之间有一个很重要的区别,特别是在判断条件上

正确的解释是:“==允许在相等比较中进行强制类型转换,而===不允许。

==和===都会检查操作数的类型。区别在于操作数类型不同时它们的处理方式不同。

(1) 如果Type(x)是数字,Type(y)是字符串,则返回x == ToNumber(y)的结果。

(2) 如果Type(x)是字符串,Type(y)是数字,则返回ToNumber(x) == y的结果

==最容易出错的一个地方是true和false与其他类型之间的相等比较。

image.png 推荐这样写

image.png

语句都有一个结果值(statement completionvalue, undefined也算)


try...finally

finally中的代码总是会在try之后执行,如果有catch的话则在catch之后执行。也可以将finally中的代码看作一个回调函数,即无论出现什么情况最后一定会被调用

如图例所示

1.如果try中有return语句会出现什么情况呢

image.png

2.try 抛出错误

image.png

3.如果finally中抛出异常(无论是有意还是无意),函数就会在此处终止。如果此前try中已经有return设置了返回值,则该值会被丢弃:

image.png

4.finally中的return会覆盖try和catch中return的返回值

image.png

switch

image.png switch中case表达式的匹配算法与===相同,case中还可以出现各种表达式,它会将表达式的结果值和true进行比较。

1.因为a == 42的结果为true,所以条件成立。 image.png

2.因为(a || b == 10)的结果是"hello world"而非true,所以严格相等比较不成立。此时可以通过强制表达式返回true或false,如case ! ! (a || b == 10): image.png


一个不太为人所知的事实是:由于浏览器演进的历史遗留问题,在创建带有id属性的DOM元素时也会创建同名的全局变量

image.png