JS一定要摳細(xì)節(jié)掖蛤,邏輯性。我們這次探討 內(nèi)存 的問(wèn)題井厌、一個(gè)IE的BUG以及深拷貝和淺拷貝蚓庭,和typeof運(yùn)算符的小技巧
在第一集里面知道了7個(gè)基本的數(shù)據(jù)類(lèi)型
number string boolean symbol null underdefined object
那么這七個(gè)數(shù)據(jù)類(lèi)型如何轉(zhuǎn)換呢
其他數(shù)據(jù)類(lèi)型轉(zhuǎn)string
- String()函數(shù)
String(0)
"0"
String(true)
"true"
String(false)
"false"
String(null)
"null"
String(undefined)
"undefined"
String({})
"[object Object]"
String({name: 9})
"[object Object]"
- toString()屬性
注意null和undefined只是兩個(gè)值,沒(méi)有toString()屬性
null.toString()
VM371:1 Uncaught TypeError: Cannot read property 'toString' of null
at <anonymous>:1:6
(anonymous) @ VM371:1
undefined.toString()
VM400:1 Uncaught TypeError: Cannot read property 'toString' of undefined
at <anonymous>:1:11
(anonymous) @ VM400:1
還有一個(gè)要注意的
{}.toString()
VM91:1 Uncaught SyntaxError: Unexpected token .
({}).toString()
"[object Object]"
其他的都可以
var a = 8;
a.toString()
"8"
var a = true
a.toString()
"true"
var a = {}
a.toString()
"[object Object]"
- 最常見(jiàn)的方法 ' '+
無(wú)敵的方法
'' +1
"1"
''+ true
"true"
''+ null
"null"
''+ undefined
"undefined"
其它數(shù)據(jù)類(lèi)型轉(zhuǎn)number
- Number()函數(shù)
Number('fff')
NaN
Number('30')
30
Number(null) //注意是0
0
Number(undefined) //注意是NaN
NaN
Number(true)
1
Number(false)
0
- parseInt()和parseFloat()屬性
parseInt()有個(gè)大坑仅仆,是從左邊第一個(gè)字符開(kāi)始看器赞,不是數(shù)字,就停下了墓拜,而不是我理解 的有幾個(gè)數(shù)字就打印幾個(gè)數(shù)字
parseInt('122') //默認(rèn)是十進(jìn)制
122
parseInt('011')
11
parseInt('011', 2) //規(guī)定是二進(jìn)制
3
parseInt('123', 10)
123
parseInt('011', 8) //規(guī)定是八進(jìn)制
9
parseInt('A09') //發(fā)現(xiàn)第一個(gè)字符就不是數(shù)字港柜,不往后面判斷了
NaN
parseInt('09A12')
9
parseFloat('11.4')
11.4
- 沒(méi)見(jiàn)過(guò)的操作
其他數(shù)據(jù)類(lèi)型-0
null-0
0
undefined-0
NaN
'91' - 0
91
'91.09' - 0
91.09
'str' - 0
NaN
var a = {}
a-0
NaN
var a = '123'
a-0
123
- 又是一個(gè)沒(méi)見(jiàn)過(guò)的操作
+ ''
+'124'
124
+'12.4'
12.4
+false
0
+true
1
+null
0
+undefined
NaN
其它數(shù)據(jù)類(lèi)型轉(zhuǎn)成boolean
注意5個(gè)特殊的falsey值,當(dāng)然了false必然也是falsey值
0
NaN
' ' 這是空字符串咳榜,啥也沒(méi)有夏醉,空格也沒(méi)有
null
undefined
除了以上6個(gè)falsey值,其他的都是true
- Boolean()函數(shù)
Boolean('')
false
Boolean(' ')
true
Boolean(0)
false
Boolean(NaN)
false
Boolean(null)
false
Boolean(undefined)
false
Boolean([])
true
Boolean({})
true
Boolean(9)
true
Boolean('pp')
true
-
!!
的操作
怎么理解呢涌韩,一個(gè)!
是取反的操作畔柔,再加一個(gè)就是雙重取反,就是我們想要的結(jié)果了
!0
true
!1
false
!!0
false
!!NaN
false
!!''
false
!!null
false
!!undefined
false
!!1
true
!!'pp'
true
!![]
true
!!{}
true
四個(gè)經(jīng)典的內(nèi)存題
粗糙的內(nèi)存圖的引入
var a = 1 和var a = new Number(1)分別發(fā)生了什么
簡(jiǎn)單數(shù)據(jù)類(lèi)型存在stack中臣樱,存儲(chǔ)位置是連續(xù)的靶擦,像彈匣一樣腮考,與數(shù)據(jù)結(jié)構(gòu)中的棧一樣,先進(jìn)后出(FILO)玄捕,而復(fù)雜數(shù)據(jù)類(lèi)型存儲(chǔ)在heap中踩蔚,存儲(chǔ)位置不連續(xù),與數(shù)據(jù)結(jié)構(gòu)中的堆一樣,是樹(shù)狀的發(fā)散結(jié)構(gòu),這一點(diǎn)超級(jí)重要啊。時(shí)時(shí)刻刻要記著數(shù)據(jù)結(jié)構(gòu)啊。第一個(gè)題 簡(jiǎn)單數(shù)據(jù)類(lèi)型的判斷 a=?
var a = 1
b = a
b = 2
a
1
答案是a=1
- 第二個(gè)題 復(fù)雜數(shù)據(jù)類(lèi)型 的判斷 a =?
var a = {name: 'wushao'}
b =a
b={name: 'shao'}
a
{name: "wushao"}
答案是a={name: 'wushao'}耀找,結(jié)果不變
- 第三個(gè)題 復(fù)雜數(shù)據(jù)類(lèi)型 的判斷 a.name=?
var a = {name: 'wushao'}
b =a
b.name = 'qwert'
a.name
"qwert"
答案是a.name = 'qwert',已經(jīng)被b.name改變了
- 第四個(gè)題 復(fù)雜數(shù)據(jù)類(lèi)型 的判斷 a=?
var a = {name: 'a'}
var b = a
b = null
a
{name: "a"}
答案是 a = {name: "a"} 不受b的影響
一個(gè)很賤的面試題
var a = {n: 1}
var b = a
a.x = a = {n: 2}
alert(a.x) //是啥呢 undefined
alert(b.x) //是啥呢 [object Object]
IE6 的關(guān)于垃圾回收機(jī)制的一個(gè)BUG
有以下情形
var fn = function( ){ }
document.body.onclick = fn
fn = null
問(wèn)你 function(){}是不是垃圾
-
第一種情況,你沒(méi)有關(guān)閉這個(gè)tab頁(yè)
那么function不是垃圾
-
第二種情況洋幻,我關(guān)閉了這個(gè)tab頁(yè),那么function就是垃圾了
IE6的BUG在于讲竿,你關(guān)閉了網(wǎng)頁(yè),但是藍(lán)色圓里面的他不認(rèn)為是垃圾庄涡,除非你關(guān)閉瀏覽器量承。所以你要在網(wǎng)頁(yè)關(guān)閉的時(shí)候手動(dòng)加上一個(gè)
//onunload不加載,就是關(guān)閉了嘛
window.onunload = function(){
document.body.onclick = null; //所有的都要有
}
由以上幾個(gè)題引出深拷貝和淺拷貝 的問(wèn)題
深拷貝是你改變了穴店,原來(lái)的不受改變的影響撕捍,而淺拷貝會(huì)改變?cè)瓉?lái)的屬性。
對(duì)于簡(jiǎn)單類(lèi)型的數(shù)據(jù)來(lái)說(shuō)泣洞,賦值就是深拷貝忧风。
對(duì)于復(fù)雜類(lèi)型的數(shù)據(jù)(對(duì)象)來(lái)說(shuō),才要區(qū)分淺拷貝和深拷貝球凰。
typeof運(yùn)算符的坑
JavaScript有三種方法狮腿,可以確定一個(gè)值到底是什么類(lèi)型。
typeof 運(yùn)算符
instanceof 運(yùn)算符
Object.prototype.toString方法
typeof運(yùn)算符可以判斷你要的值得數(shù)據(jù)類(lèi)型呕诉,有如下結(jié)果
先看大坑
typeof null
"object"
typeof Function
"function"
function f(){}
typeof f
"function"
函數(shù)竟然是function類(lèi)型的數(shù)據(jù)缘厢,坑爹啊。
null竟然是object甩挫,尼瑪贴硫,嚇壞了,一查原來(lái)是歷史遺留問(wèn)題伊者。
1995年JavaScript語(yǔ)言的第一版英遭,所有值都設(shè)計(jì)成32位,其中最低的3位用來(lái)表述數(shù)據(jù)類(lèi)型亦渗,object對(duì)應(yīng)的值是000挖诸。當(dāng)時(shí),只設(shè)計(jì)了五種數(shù)據(jù)類(lèi)型(對(duì)象央碟、整數(shù)税灌、浮點(diǎn)數(shù)均函、字符串和布爾值),完全沒(méi)考慮null菱涤,只把它當(dāng)作object的一種特殊值苞也,32位全部為0。這是typeof null返回object的根本原因粘秆。
為了兼容以前的代碼如迟,后來(lái)就沒(méi)法修改了。這并不是說(shuō)null就屬于對(duì)象攻走,本質(zhì)上null是一個(gè)類(lèi)似于undefined的特殊值殷勘。
你只需要記住,null不是對(duì)象 昔搂!null不是對(duì)象玲销! null不是對(duì)象!就是一個(gè)值null摘符。
其他的類(lèi)型是符合預(yù)期的
typeof 123
"number"
typeof '123'
"string"
typeof true
"boolean"
typeof []
"object"
typeof {}
"object"
判斷某變量是否存在的兩個(gè)技巧
- 下面演示的是第一種方法
typeof undefined
"undefined"
typeof a
"undefined"
上面的a未聲明,直接使用會(huì)報(bào)錯(cuò)
a
VM412:1 Uncaught ReferenceError: a is not defined
at <anonymous>:1:1
但是用了typeof就可以啦
可以用來(lái)判斷某個(gè)變量是否聲明了
if (typeof v === "undefined") {
// ...
}
除了上述的方法贤斜,還有另外一個(gè)利用全局對(duì)象的屬性的方法
if ('a' in window) {
// 變量 a 聲明過(guò)
} else {
// 變量 a 未聲明
}
- 區(qū)分?jǐn)?shù)組還是對(duì)象的技巧
既然typeof對(duì)數(shù)組(array)和對(duì)象(object)的顯示結(jié)果都是object,那么怎么區(qū)分它們呢逛裤?instanceof運(yùn)算符可以做到瘩绒。
var o = {};
var a = [];
o instanceof Array // false
a instanceof Array // true