前几天开始耐下心来开始看书,不知不觉已经快要看完《你不知道的JavaScript》丛书的第二本了。下面整理一下,我做的笔记。顺便看一下自己的博客主题风格还有什么需要改进的地方,顺势就调整一下好了……
第1章 类型
1.2 内置类型
7种内置类型:
- null
- undefined
- boolean
- number
- string
- object (子类型: function, array等)
- symbol
特殊:typeof null === ‘object’; //true
办法:使用符合条件,例如(!a && typeof a === ‘object’); //若 a = null 则为 true,用以区分null和object
函数的length是其声明的参数个数。
1.3 值作为类型
- JavaScript中的变量是没有类型的,而是判断变量的值的类型。
- 变量声明但未赋值时为
undefined
- 变量未声明是为
undeclared
,抛出ReferenceError - 用typeof来检测
undeclared
变量不会抛出异常
第2章 值
2.2 字符串
- 字符串是不可变的(不会改变其原始值,而是创建并返回新的字符串),而数组是可变的
- 字符串可以“借用”数组的非变更方法
2.3 数字
- “整数”就是没有小数的十进制数
- JS用的是“双精度”格式,即64位二进制
- 误差范围值:
Number.EPSILON
, 也就是2^-52 - 整数最大能够达到53位,最大安全整数2^53 – 1
- 有些数字操作只适用于32位数字
2.4 特殊数值
null
指空值(empty),或曾有值可当前没有值undefined
指缺失值(missing),或从未赋值- 要将代码中的值返回undefined,可以使用
void
NaN
是number类型,但是它代表“无效数值”,它和自身不想等,唯一一个没有自反的值- 计算结果一旦溢出为
Infinity
就无法回到有穷,Infinity/Infinity
结果为NaN - 虽然
-0 === 0
但是-0是个奇怪的存在,数字-0转为字符串的时候会变成”0″
Object.is(..)主要用以处理特殊的相等比较
2.5 值和引用
- JavaScript中的变量不可能成为指向另一个变量的引用
- JavaScript中引用指向的是值
- 简单值(null, undefined, string, number, boolean, symbol) 通过值拷贝的方式赋值或传递
- 复合值(object(含array、封装对象), function) 通过引用拷贝的方式赋值或传递
第3章 原生函数
new String("abc")
创建的是字符串”abc”的封装的对象,而非基本类型值”abc”- 可以使用
Object。prototype.toString()
查看object
的内部属性[[Class]] - 应当优先使用基本类型,而不是封装对象
3.4.1 Array()
- Array不要求必须带
new
- Array构造函数只带一个参数时,该参数绘本作为数组预设长度(length)
- 空单元有别于值为undefined单元:[undefined x 3] 和 [undefined, undefined, undefined]
Array.apply(null, {length: 3})
比Array(3)
更可靠,前者返回[undefined, undefined, undefined],后者返回[undefined x 3]
3.4.2 Object(), Function(), RegExp()
- 除非动态定义(传入变量),否则尽量不要使用这三者的构造函数,应当使用字面形式
3.4.3 Date(), Error()
- Date() 不带参数则使用当前时间
- Date() 以 秒(s) 为单位
- Date() 调用时不带
new
会返回当前时间的字符串值 - Error() 带不带
new
均可,通常与throw一起使用 - 创建错误对象主要是为了获得当前运行栈的上下文
3.4.4 Symbol()
- 不能带
new
关键字,否则会出错 - Symbol主要用于私有或特殊属性,用它来明明对象属性不容易导致重名
- Symbol并非object,而是一种简单标量基本类型
第4章 强制类型转换
JS中的强制类型转换总是返回简单值(标量基本类型值)
ToString
- 规则:null转为”null”, undefined转为”undefined”,true转为”true”等
- 如果对象中定义了toJSON()方法,JSON.stringify()会优先调用,然后以其返回值进行序列化
- toJSON() 应该“返回一个能够被字符串化的 安全 JSON值,而不是JSON字符串
ToNumber
- 规则:先转化为基本类型( 先看valueOf(),若没有则toString() )后,再强制转换。( ToPrimitive 抽象操作)
- true转为1
- false转为0
- undefined转为NaN
- null转为0
ToBoolean
- Falsy值:undefined, null, false, +0, -0, NaN, “”
- Truthy值:Falsy值之外的值,包括:[], {}, function(){}, “””等
- Falsy对象:形如 new Boolean(false),由浏览器给JavaScript添加的 外来 值
4.3 显式强制类型转换
字符串<->数字
- 使用 String() 和 Number()
- 实用形如:
+"42.5"
,+new Date()
(最好使用 Date.now() )等 ~x
大致等同于 -(x+1),indexOf()可以结合 ~ 来隐藏底层细节:若indexOf()返回-1,~可将其转为假值0~~
可以截除数字的小数部分(原理是执行ToInt32做两次逐位取反),不同的是Math.floor()会四舍五入- 解析(如使用
parseInt()
)遇到字符串就停止,转换(如使用Number()
)则不允许出现非数字 parseInt()
会先将参数强制转换为字符串再解析:如parseInt(0.0000008)即为parseInt(“8e-7”),结果为8
*->布尔值
建议使用Boolean(a)和!!a做强制转换
4.4 隐式强制类型转换
字符串<->数字
- 如果 + 的其中一个操作数是字符串,则执行拼接
[]+{}
返回 [object Object];{}+[]
返回 0- 使用 – 可以将字符串转换为数字,例如
a - 0
,当然a * 1
和a / 1
也是可行的,但不常见 - 遇到操作数是对象(如数组)会调用ToPrimitive将其转为字符串后再操作
布尔值->数字
将boolean通过累加的方式,减少&&
和||
表达式
*->布尔值
a||b
结果为true,则返回 a,相当于 a ? a : ba&&b
结果为true,则返回 b,相当于 a ? b : a
符号(Symbol)
- 允许:转为布尔值,显式转为字符串(如
String(sym)
) - 禁止:转为数字,隐式转为字符串(如
sym+""
)
4.5 宽松等价与严格等价
== 允许在等价性比较中进行强制转换,而 === 不允许强制转换
如果两个值是同一类型,仅比较是否相等(例外:+0 等于 -0,NaN 不等于 NaN)
- string与number比较:string转成number
- 任何类型与boolean比较:boolean转成number
- null与undefined比较:
==
中互相等价 - object与非object比较:对象ToPrimitive操作,变为数字
假值的相等比较——坑!
- “0” == false; // true
- false == 0; // true
- false == “”; // true
- false == []; // true
- “” == 0; // true
- “” == []; // true
- 0 == []; // true 其中有4个与
== false
比较有关,应当 总是 避免
极端情况:
- [] == ![]; // true (![]转换变成了false)
- “” == [null]; // true ([null]会转换成字符串再比较)
- 0 == “\n”; // true (空字符串会变成0再比较)
为了避免这样的比较中的问题,这里有一些可以遵循的 原则:
- 如果比较的任意一边可能出现true或者false值,那么就永远,永远不要使用==。
- 如果比较的任意一边可能出现[],””,或0这些值,那么认真地考虑不使用==。 在这些场景中,为了避免不希望的强制转换,最好使用
===
。
相关资料:JS中相等的比较
4.6 抽象关系比较
- 将
<=
考虑为“不大于” - a <= b 会被考虑为
b < a
的反转
第5章 语法
5.1 语句和表达式
所有语句都有完成值(即使这个值只是undefined)
对于++a++来说,a++这部分会首先被求值,返回42(举例),然后它试着对++42求值,这时会给出ReferenceError错误
var a = b = 42将不会直接声明b
操作符优先级列表:Operator Precedence | MDN
5.2 操作符优先级
短路 :对于&&和||而言,如果左侧操作数足够确定操作的结果,那么右侧操作数将被忽略。
- && 高于 ||, || 高于 ? :
- 关联和执行顺序不是一回事
不要同时访问命名参数和其对应的arguments数组单元
5.6 try…finally
- finally中的代码总是在try之后执行,若有catch则在catch之后
- 无论出现什么情况,finally最后一定会调用
- 如果finally抛出异常,函数就会在此终止
- finally不会再yield之后立即执行
- finally中的return会覆盖try和catch中的return返回值
附录
- 一些假值对象在强制转换为boolean时,会意外地称为假值而非真值。
- HTML页面中的id属性会创建同名的 全局变量
- 不要扩展原生原型,除非加入判断条件(尽力避免)
- 同一页面中 多个
<script>
共享global对象 - 作用域的提升机制在
<script>
边界不适用 - 一个
<script>
发生错误会停止,后续<script>
接着运行
收拾心情,开始啃一本本书了,温故而知新嘛!
发表回复