JS里的类型转换
任意类型转字符串
xxx.toString()
(1).toString() // "1" true.toString() // "true" null.toString() // Uncaught TypeError: Cannot read property 'toString' of null undefined.toString() // Uncaught TypeError: Cannot read property 'toString' of undefined {}.toString() // Uncaught SyntaxError: Unexpected token . ({}).toString() // "[object Object]"
String(xxx)
String(1) // "1" String(true) // "true" String(null) // "null" String(undefined) // "undefined" String({}) // "[object Object]"
xxx + ''
,当然这种方法更简便1 + '' // "1" true + '' // "true" null + '' // "null" undefined + '' // "undefined" {} + '' // 0 var obj = {} obj + '' // "[object Object]"
任意类型转布尔
Boolean(xxx)
!!xxx
,老司机专用手法!!null // false !!undefined // false
5个 falsy 值
0 NaN '' null undefined
任意类型转数字
Number(xxx)
parseInt(xxx, 10)
parseFloat(xxx)
xxx - 0
+ xxx
内存图
来看几道题目:
var a = 1
var b = a
b = 2
//请问 a 显示是几?
var a = {name: 'a'}
var b = a
b = {name: 'b'}
//请问现在 a.name 是多少?
var a = {name: 'a'}
var b = a
b.name = 'b'
//请问现在 a.name 是多少?
var a = {name: 'a'}
var b = a
b = null
//请问现在 a 是什么?
注:每当遇到这种问题,就老实地画一下内存图,把栈内存(Stack)和堆内存(Heap)都画出来,结果就会一目了然了。
- 简单类型的数据直接存在 Stack 里
- 复杂类型的数据是把 Heap 地址存在 Stack 里
另外,我在《JavaScript高级程序设计》4.1.3–传递参数 一文中也解释过类似的问题,可以结合着看。
再来看一道题:
var a = {n:1}
var b = a
a.x = a = {n:2}
alert(a.x) //undefined
alert(b.x) //[object Object]
注意画图来理清思路。
关于循环引用
错误的例子:
var a = {self: a}
a.self //undefined
因为在赋值操作进行之前, 对象里 a 的值还是未声明的状态,值为 undefined
正确的写法:
var a = {}
a.self = a
a.self
//你可以一直 a.self.self.self 下去
垃圾回收
GC 垃圾回收
如果一个对象没有被引用,它就是垃圾,将被回收。
来看一下简单的题目:
var fn = function() {}
document.body.onclick = fn
fn = null
//请问例子中的函数现在是不是属于垃圾
IE6有BUG内存泄露,关掉当前页面,并不会把document引用的对象视为垃圾,除非整个浏览器关闭。
解决方法也是有的,就是手动设置一下
window.onunload=function (){document.body.onclick=null}
深拷贝和浅拷贝
基本类型赋值都是深拷贝,即拷贝后两者的值不互相影响
var a = 1 var b = a b = 2 a // 1 b // 2
复杂类型,对象的赋值就属于浅拷贝
var a = {name: 'Jonathan'} b = a b.name = 'Jack' a.name // 'Jack'
(完)