第一部分 类型与语法
第一章 类型
总结:
- JavaScript 有 七 种 内 置 类 型:null、undefined、boolean、number、string、object 和symbol,可以使用 typeof 运算符来查看。 变量没有类型,但它们持有的值有类型。类型定义了值的行为特征。
- 很多开发人员将 undefined 和 undeclared 混为一谈,但在 JavaScript 中它们是两码事。 undefined 是值的一种。undeclared 则表示变量还没有被声明过。
- 遗憾的是,JavaScript 却将它们混为一谈,在我们试图访问 "undeclared" 变量时这样报 错:ReferenceError: a is not defined, 并 且 typeof 对 undefined 和 undeclared 变 量 都 返 回 "undefined"。
- 然而,通过 typeof 的安全防范机制(阻止报错)来检查 undeclared 变量,有时是个不错的 办法。
第二章 值
2.1 数组
2.2 字符串
2.3 数字
2.4 特殊数值
2.5 值和引用
小结
-
JavaScript 中的数组是通过数字索引的一组任意类型的值。字符串和数组类似,但是它们的 行为特征不同,在将字符作为数组来处理时需要特别小心。JavaScript 中的数字包括“整 数”和“浮点型”。
-
基本类型中定义了几个特殊的值。null 类型只有一个值 null,undefined 类型也只有一个值 undefined。所有变量在赋值之 前默认值都是 undefined。void 运算符返回 undefined。数字类型有几个特殊值,包括 NaN(意指“not a number”,更确切地说是“invalid number”)、+Infinity、-Infinity 和 -0。
-
简单标量基本类型值(字符串和数字等)通过值复制来赋值 / 传递,而复合值(对象等) 通过引用复制来赋值 / 传递。JavaScript 中的引用和其他语言中的引用 / 指针不同,它们不 能指向别的变量 / 引用,只能指向值。
第三章 原生函数
小结
JavaScript 为基本数据类型值提供了封装对象,称为原生函数(如 String、Number、Boolean 等)。它们为基本数据类型值提供了该子类型所特有的方法和属性(如:String#trim() 和 Array#concat(..))。
对于简单标量基本类型值,比如 "abc",如果要访问它的 length 属性或 String.prototype 方法,JavaScript 引擎会自动对该值进行封装(即用相应类型的封装对象来包装它)来实 现对这些属性和方法的访问。
第四章 强制类型转换
4.1 值类型转换
4.2 抽象值操作
4.3 显式强制类型转换
4.4 隐式强制类型转换
因为数组的 valueOf() 操作无法得到简单基本类型值,于是它转而调用 toString()。因此上例中的两 个数组变成了 "1,2" 和 "3,4"。+ 将它们拼接后返回 "1,23,4"。
var a = [1,2];
var b = [3,4];
a + b; // "1,23,4"
字符串和数字之前的隐式强制类型转换也有它的用处
b=String(a) //显式
b=a+""
下面几种情况会发生布尔值隐式强制类型转换
- if(...)语句中的条件判断表达式
- for(..;..;..;)语句中的条件判断表达式
- while(...)和do...while(...)循环中的条件判断语句
- ? ... : ... 的条件判断表达式
- 逻辑运算符 ||(逻辑或)和&&(逻辑与)左边的操作数(作为条件判断表达式)
补充:
1、逻辑运算符 ||和&&其实称之为选择器运算符、操作数运算符更为恰当。因为他们不同于其他语言,js中返回的并不是返回布尔值。他们返回的是选择操作数中的一个,然后返回它的值
-
a||b 相当于 a?a:b
-
a&&b 相当于 a?b:a 2、还有一种用法常出现在代码压缩工具汇总。就是第一个操作数为真值,则&&运算符“选择”第二个操作数作为返回值,也叫做“守护运算符”
-
a && foo()
foo()只有在条件判断a通过的时候才会被调用。如果条件判断未通过,a && foo() 就会悄然终止。 3、那么既然返回的不是布尔类型,为什么 a&&(b||c)这样的表达式在if和for中没出现过问题呢,
var a = 42; var b = null; var c = "foo"; if (a && (b || c)) { console.log( "yep" ); }这里a && (b || c)的结果实际上是“foo”而非true,然后再由if将foo强制转换成布尔值
4、ES6引入符号类型,他的强制类型转换有一个坑,ES6允许从符合到字符串显示强制类型转换,然而隐式强制类型转换会产生错误。 符号不能被强制转换成数字,但是可以被强制类型转换为布尔值
4.5 宽松相等和严格相等
宽松相等 ==
严格相等 ===
这两种比较并不是如很多书籍和博客中所说的“== 检查值是否相等,=== 检查值和类型是否相等”,
然而正确的解释是“==允许在相等比较中进行强制类型转换,而===不允许”
相等操作符,性能比较
类型转换确实会多花时间,但是往往是微妙级别的差别而已。选择的时候需要考虑强制类型转换就用==,不用在乎性能。
抽象相等
-
1、其他类型和布尔值的相等比较
var a=66 a==true //false // 不要这样用,条件判断不成立: if (a == true) { // .. } // 也不要这样用,条件判断不成立: if (a === true) { // .. } // 这样的显式用法没问题: if (a) { // .. } // 这样的显式用法更好: if (!!a) { // .. } // 这样的显式用法也很好: if (Boolean( a )) { // .. }
避免 == true和 ==false 我们就不需要担心这些坑了
-
2、null和undefinned之间相等比较
(1) 如果 x 为 null,y 为 undefined,则结果为 true。
(2) 如果 x 为 undefined,y 为 null,则结果为 true。
(3) == 中 null 和 undefined 相等(它们也与其自身相等),除此之外其他值都不存在这种情况。
也就是说在 ==中 null和undefined是一回事,可以相互隐式强制类型转换,并且这种强制类型转换是安全可靠的。除了null和undefined以外,其他值均无法得到假阳结果,个人认为通过这种方式将null和undefined作为等价来处理比较好。
-
3、列出非常规情况
-
4、极端情况
[] ==![] //true 其实变成了 [] == false
2==[2] //true ,[2]会转换成2
"" == [null] //true [null]直接转换成""
0=="\n" //true
-
5、注意
• 如果两边的值中有 true 或者 false,千万不要使用 ==。
• 如果两边的值中有 []、"" 或者 0,尽量不要使用 ==。
第五章 语法
5.1 语句和表达式
var a=3*6;
var b=a;
b;
分析:
- 1、这里的3*6是一个表达式,第二行a也是一个表达式,第三行b也是
- 2、这三行代码都是包含表达式的语句。var a=3*6;、var b=a;被称之为 “声明语句”
- 3、a=3*6; b=a;(不带var)叫做 “赋值表达式”
- 4、第三行虽然只有表达式b,但是同时他也是语句。这种情况通常成为 “表达式语句”