在上一篇笔记中,主要是说明了原始值的相关细节。本篇笔记主要内容是简要地介绍一下对象,js的类型转换。
(一)全局对象和包装对象
/* 全局对象 */
1. 什么是全局对象:
(1)当JavaScript解释器启动时(或者Web浏览器加载新的页面时),将会创建一个新的全局对象,这个全局对象会被定义一组初始属性,包括全局属性,全局对象,全局函数,构造函数;
(2)全局对象的初始属性并不属于保留字,但是应该当做保留字来对待;
2. 全局对象的引用
在代码的最顶级,可以使用关键字this来引用全局对象
3. 在浏览器窗口中的所有代码中,window对象来充当全局对象
4. window对象定义了核心全局属性,同时也针对浏览器和客户端定义了少部分其他属性
5. 当初次创建的时候,全局对象定义了js中所有的预定义全局值
6. 全局对象同样也包含了为程序定义的全局值,如果代码声明了一个全局变量,那么这个全局变量也是全局对象的一个属性
/* 包装对象 */
7. 对于简单值来讲其实不存在方法的,但是简单之所以可以调用方法,如字符串 s.length,是因为一旦引用了s的属性,js就会将字符串通过new String()的方式转换为字符串对象,这个对象继承了字符串的方法,并被用来处理属性的应用,一但引用结束,这个对象就会被销毁。类似的情况也会发生于数字和布尔值类型上,这个临时对象就是包装对象。
8. 注意:null和undefined没有包装对象,所以访问他们的属性时会报错
9. 注意:可以通过String(),Number(),Boolean()来显式创建包装对象;在判断相等的时候,同一个值的包装对象和原始值在‘==‘时是相等,在‘===‘时不相等
(二)原始值和对象的比较方式
1. 原始值的值是不可变的,对象的值是可变的
2. 原始值的比较是值的比较:只有在它们的值相等时,它们才相等
3. 对象的比较并非值的比较,即便两个对象包含同样的属性和同样的值,它们也不相等,因为对象属于引用类型,它们的‘值’是引用,所有对象的比较是引用的比较
(三)类型转换
1. js可以做自动的类型转换
2. 原始值到原始值的转换 (详细的转换规则见犀牛书第6版 49页)
3. 原始值到对象的转换比较简单,使用String(),Number(),Boolean();注意:null和undefined比较例外
4. 对象转换为原始值:
(1)对象转换为布尔值:所有的对象(包括函数和数组)都转换为true
(2)对象到字符串或数字:
- 宿主对象(如由浏览器定义的对象)根据各自的算法可以转换为字符串和数字
- 本地对象通过继承的两个方法来转换:toString(),valueOf()
- toString():很多类定义了更多特定的版本,数组类的toString将每个数组元素转换成一个字符串,并在元素之间添加逗号后合并成结果字符串;函数类是返回这个函数的实现定义的表示;日期类是返回一个可读的日期和时间字符串;RegExp类是返回表示正则表达式直接量的字符串
- valueOf():如果存在原始值,它就默认将对象转换为表示它的原始值;如果对象无法表示原始值,它就返回对象本身;数组,函数和正则对象都是返回本身;日期类hi返回一个内部表示,即1970年1月1日以来的毫秒数
- 对象转为字符串的过程:如果对象有toString方法,则调用这个方法,将结果转换为字符串;如果没有toString,或者这个方法并不返回一个原始值,那么js会调用valueOf()方法,如果存在就则调用它,返回的是原始值的话则转换为字符串;否则,js无法从toString或者valueOf获得原始值,此时报错。
- 对象转换为数字:如果对象有valueOf方法,则调用该方法并返回一个原始值,js将此原始值转换为数字;否则如果对象有toString方法,则返回一个原始值,js将此原始值转换为数字返回;否则,抛出异常
(3)日期对象转换为原始值:通过valueOf或toString返回的原始值将被直接使用,而不会强制转换为数字或字符串
(4)除了日期外,任何对象要转换为原始值都会先尝试调用valueOf,然后调用toString