? ? ?前段學習js的時候總是零零散散的,以至于很多東西都模棱兩可。時間稍微一久,就容易忘記。最主要的原因是這些東西,原來學的時候就不是太懂,以至于和其他知識無法形成記憶鏈,所以孤零零的知識特別容易忘記。重溫犀牛書,加上最近對記憶宮殿的記憶方法有點感興趣,于是結合起來來做筆記。
?
開始吧,上去先扔一張我畫的js的數據類型。后面的所有東西,基本上都是基于這張圖的。
?
?
原始類型沒啥說的,就是string,number ,boolean 。
? ? ? 對象類型包括 對象。其實還有Array, func 也是特殊的對象。 ?對象其實就是一個鍵值對,在php里面叫關聯數組。值可以是原始類型即string, boolean、number,當然也可以還是一個對象。
? ? ? 這里面有兩個特殊的東西,叫null和undefined。null在各種語言里都比較常見。在js里面null == undefined。這兩個特殊的東西,叫做特殊的原始值,因為其數據類型就是其值,其值不能被修改(不可變 immutable).null和undefined的區別在哪里呢?區別在于null常表示我們程序級別的,正常的空值。如變量沒有賦值的時候,到了瀏覽器語法檢查的時候,會在該變量作用域的頂部聲明該變量,這個時候給這個變量賦的值就是null.但是當該變量不存在的時候,下面卻調用了,就會報undefined,因此可以認為undefined是系統級別的,類似于語法錯誤。?
? ? ? 有對象就有類,對象是實例化的類。js的對象是一個大對象,當create一個頁面的時候,就會被js構造器(construct)創造出來 數組對象(Array)、函數對象(function)、日期對象(date)、正則對象(RegExp)以及錯誤對象(Error).這點稍后會詳細的講下。
? ? ? 上面是從從數據類型維度來區分js的值的。數據類型是后面的基礎,從是否擁有方法又可以區分,可以擁有方法的類型,不擁有方法的類型。可變的類型,與不可改變的類型、
從擁有方法來講,其實原始類型是不擁有方法的,但是js的特殊性卻讓原始類型也擁有了方法。比如toString()的方法。這些不擁有方法的類型在調用方法的時候,會先變成包裝對象(一個調用后立即銷毀的對象),所以原始類型也是擁有方法的類型。但是特殊的類型 null 與 undefined 不擁有方法,因為其值不允許被改變,有方法有個毛用啊。
? ? ?從值可變與不可變的角度來說。原始類型的值是不能被改變的。平時在使用的過程中,確實發現其值改變了,那是因為我們將改變后的值賦給了新的變量。其原變量本身是沒有變化的。字符串是由字符組成的數組,這點和C語言一樣,比較好理解。
?
直接量:
什么叫直接量,就是簡單直接粗暴的賦值。類似 var a = 3; ??
直接量,直接賦值。區別于調用new String() ?new Number() 來產生的變量。使用直接量,程序沒有執行的時候,并不知道值得類型,等到語法解析編譯的時候,才會根據其具體的值,指定變量類型。因此這樣的方式聲明的變量就叫做直接量。
?
全局對象
瀏覽器啟動,create一個新的頁面。js的全局對象已經被創造好了。也就是一個大對象生下了一堆小對象。對于大對象來說,這是一堆小對象,但是對于我們來說。他們仍是一個對象類,我們需要去實例化。
大對象生出了一堆東西:
全局屬性: undefined、Infinity、Nan
全局函數:isNaN() ?、parseInt() 、eval()
構造函數:(我更喜歡稱為構造類)Date() 、RegExp()、String() 、Object() 、Array(). 之所以稱為是構造函數,是因為我們也可以直接把他們當做函數使用,在原始類型變成對象的時候,也充當包裝對象。
全局對象: Math() 、JSON。
?
包裝對象
這個名字起的比較好。假設原始類型string 、number 、boolean 分別是烤雞、烤鴨、烤兔。當他們變成商品(對象)去賣的時候、就會包上一層包裝紙,錫箔紙、包裝袋。但是這個包裝紙的作用是有限的,當其完成其固有的作用的時候,就會被丟棄(包裝對象被銷毀)。
所謂的包裝對象就是用完就丟棄,就像物品的包裝袋一樣。
?
類型轉換:
這個分為原始類型之間的轉換、對象之間的轉換、原始類型轉為對象、對象轉為原始類型三部分。
原始類型之間互轉主要通過內隱的方法進行自動轉換,也可以調用系統的構造函數。
原始類型變對象,通過包裝對象。
對象變原始類型。主要是變成字符串和數字兩種。 通過調用對象內的一個魔術方法。這個原理和php里面的將變量變成當成字符串輸出的原理是一樣的。
?
變量作用域與作用域鏈:
這種東西,畫個圖什么的,就清晰多了。
?
A的變量作用域在A - E,B的變量作用域在B-E,以此類推E的變量作用域在E。
但是E想使用A的一個變量怎么辦,js不像人一樣聰明,直接去D拿,況且js也不知道變量在哪。E先問D有沒有,D要沒有了,再問C,C沒有了問B,最后一直問到A。如果A也沒有咋辦,E發現自己上當受騙了,于是跑到頂層全局對象Error() 那里告狀,然后在頁面上引發一個ReferenceError(叫你不給我,哼!)的錯誤。這點很像冒泡,也許冒泡就是從這里面來的吧。
這就是JS的作用域鏈。
?
天寒,晚安。
?