數(shù)據(jù)類型轉(zhuǎn)換
任意類型轉(zhuǎn)string:
// 使用變量屬性 toString(),null,undefined等不可用
(1).toString()
"1"
// 與空字符串相加,推薦
1 + ""
"1"
// 使用 String()
window.String(1)
"1"
任意類型轉(zhuǎn)boolean:
// 使用Boolean()
Boolean(1)
true
Boolean(0)
false
Boolean(undefined)
false
// 兩次取反
!!NaN
false
!!1
true
其他類型轉(zhuǎn)boolean后值為false的只有5種情況:null,undefined,0,"",NaN,這五個由稱作falsy值
字符串轉(zhuǎn)number:
// Number()
Number('1')
1
// parseInt()
parseInt('1')
1
parseInt('a1')
NaN
parseInt('1a')
1
// parseFloat()
parseFloat('1')
1
// 與 0 相減
'1' - 0
1
// 取正值
+ '1'
1
引用
js數(shù)據(jù)在存儲簡單類型的數(shù)據(jù)時(即通常情況下的非object類型數(shù)據(jù)),都放在stack內(nèi)存中,而復雜類型數(shù)據(jù)(object)存在heap內(nèi)存中。因此在定義一個對象時(如var a = {a: 'b'}),變量a實際上是一個對象(object)的引用,換言之,即在取值時是通過stack中存儲的地址來“間接”的獲取值,而不是像簡單類型那樣直接獲取。

數(shù)據(jù)存儲示意.png
接下來就通過幾個示例來理解數(shù)據(jù)存儲
// 簡單類型存儲
var a = 1, b = a
b === 1
true
// 改變b,a的值并不會改變,因為簡單類型存儲的值而不是引用
b = 2
a === 1
true
// 替換引用 1
// 執(zhí)行后 {name: 'foo'} 被兩個變量引用
var a = {name: 'foo'}, b = a
// 這里是用 {name: 'bar'} 替換了b的先前的引用 {name: 'foo'},而不是修改了先前的引用
b = {name: 'bar'}
a.name=== 'foo'
true
// 替換引用 2
var a = {name: 'foo'}, b = a
// 同樣的,這里用null替換了b的先前的引用 {name: 'foo'},所以a的引用還是不變
b = null
a.name === 'foo'
true
// 替換引用 3
var fn = function(){}
document.body.onclick = fn
fn = null
document.body.onclick === null
false
// 修改引用
var a = {name: 'foo'}, b = a
// 這里修改的是引用的內(nèi)部值,而a,b引用了同一個對象,所以a.name也跟著變更
b.name = 'bar'
a.name === 'bar'
true
// 讓人頭大的引用
var a = {name: 'foo'}, b = a
// 此處的坑在于,a.x 的 a 是賦值前就確定的,那么這一句就相當于下面兩句
// > a.x = {name: 'bar'}
// > a = {name: 'bar'}
// 執(zhí)行結(jié)果
// a -> {name: 'bar'}; b -> {name: 'foo', x: {'name': 'bar'}}
a.x = a = {name: 'bar'}
a.x === undefined
true
b.x.name === 'bar'
true
引用自身
// 這種引用自身的方法無效,因為a先前沒有被定義,所以是undefined
var a = {name: 'foo', self: a}
a.self === undefined
true
// 正確方式
var a = {name: 'foo'}
a.self = a
// 成功引用自身
a.self
{name: "foo", self: {…}}
a.age = 18
a.self
{name: "foo", self: {…}, age: 18}
// 可以“無限”self下去
a.self.self.self.name
"foo"
垃圾回收,簡而言之沒有被引用的值,就會被回收
// 不考慮其他因素(即a,b的值沒有其他引用的理想情況下),執(zhí)行完下面這句后,{name: 'foo'}就變成垃圾了
// 但是變量被回收的具體時間取決與瀏覽器的回收策略
var a = {name: 'foo'}, b = {name: 'bar'}, a = b