分析js
js是建立在一些非常優秀的想法和少數非常糟糕的想法之上的
優秀
- 函數
- 弱類型
- 動態對象
- 富有表現力的對象字面量表示法
糟糕的想法
全局變量綁定
儘管JavaScript有缺陷,但它真的很優秀
語法
註釋
應該使用//
,而不是/**/
標識符
建議應該由字母開頭,允許中間出現數字
和_
應該遵循一定的命名規範
數字
- Js只有一種數字類型。內部表現爲64位浮點數,沒有分離處整數類型,所以1.0和1一樣。可以避免短整型溢出問題。
- 100 = 1e2
NaN
是數值,表示不能產生正常結果的運算結果,它不等於任何值,包括自身,可以用isNaN(number)
判斷NaNInfinity
表示大於1.79……e+308的值- 數字擁有方法,包括在
Math對象
之中。
字符串
Unicode
是16位的,所以JS所有字符都是16位的- JS沒有字符類型,表示字符就創建一個包含一個字符的字符串就行
- 需要記得的幾個轉義:
\r
,\n
,\t
- “A” === “\u0041” (\u表示特定字符編碼)
- 字符串不可變,一旦創建就無法改變。可以通過
+
等運算創建一個新的字符串 - 包含完全相同字符序列的字符串被認爲是完全相同的
'c'+'a'+'t' === 'cat'
語句
js中代碼塊不會創建新的作用域,因此變量應該被定義在函數的頭部,而不是代碼塊中。
下面的值會被當成假:
- false
- null
- ”
- undefined
- 數字0
- 數字NaN
case
表達式不一定必須是常量for in
會枚舉一個對象的所有屬性(鍵名)object.hasOwnProperty()
確定屬性是該對象成員的,還是來自原型鏈for (myvar in obj) { if(obj.hasOwnProperty(myvar)) { …… } }
throw 語句中表達式一般是一個對象字面量,包含
name
和一個message
Javascript 不允許在return 和表達式之間換行 (會自動在尾部添加分號)
Javascript 不允許在break 和表達式之間換行
表達式
運算優先級
運算符優先級:基本就是一元>二元>三元
符號 | 含義 |
---|---|
. [] () | 提取屬性調用函數 |
delete new typeof + = ! | 一元 |
|
乘除,求餘 |
|
加/減 連接 |
>= <= >< | 不等 |
=== !== | 等式 |
&& | 邏輯與 |
|| | 邏輯或? |
? : | 三元 |
- %
不是傳統意義上的取模,而就是取餘(其實就是用trunc模式的取模,見我的另一篇文章)
&&
的真實含義:A?B:A,它的特性一般用來避免錯誤A.b && A.b.c
||
的含義:A?A:B ,它的特性一般用來填充默認值var color = MYAPP.color || ‘#FFF’
字面量
字面量是一個可以快速創建對象
,數組
,函數
的表示法。
- 對象字面量:屬性可以是標識符或字符串,這些名字當作字面量名而不是變量名對待,所以對象的屬性名在編譯時才知道。
- 屬性的值就是表達式
對象
介紹
簡單數據類型
Javascript的簡單數據類型包括數字
、字符串
、布爾值
、null值
、和undefined值
。其他所有的值都是對象
數字
、字符串
、布爾值
看上去是對象,因爲它們擁有方法,但是實際上,他們是不可變的
對象
概況
- js中的對象是可變的
鍵控組合
(keyed collections) 數組
、函數
、正則表達式
都是對象,當然對象也是對象- 對象是屬性的容器:
- 屬性的名字可以是空字符串在內的任意字符串
- 屬性值可以是除undefined值之外的任何值
- 對象是無類型的(class-free)。它對新屬性的名字和屬性的值沒有限制。
- 對象可以包含對象
- js包含一種
原型鏈
的特性,允許對象繼承另一個對象的屬性。正確使用能減少對象初始化的時間和內存。
對象字面量
就是包含在{}
之間的零或多個名/值
對。對象字面量可以出現在任何允許表達式出現的地方。
如果屬性名是一個合法的
標識符
,則不強制要求使用引號括住屬性名:“first-name” 是必須的
first_name 是可選的
檢索
要檢索裏面的值,可以採用[]
,如果是合法的標識符則可以用.
代替。(優先考慮.
,因爲它更加緊湊好看)
如果值不存在,會返回
undefined
||
可以用來填充默認值
var status = flight.status || “unknown”
嘗試從
undefined
中獲取屬性會報異常&&
可以用來規避錯誤
flight.equipment && flight.equipment.mode
更新
對象值可以通過賦值語句更新或者新建
引用
對象通過引用來傳遞。它們永遠不會複製!!!
原型
每個對象都會連接到一個原型對象,並且可以從它中繼承屬性。所有的對象都連接到Obeject.prototype
新建對象:
if (typeof Object.beget !== 'function'){
Object.create = function(o){
var F = function(){};
F.prototype = o;
return new F();
}
}
- 原型鏈在更新的使用不起作用(我們改變對象不會影響原型鏈)
- 如果沒有屬性,會去查原型,如果原型沒有就是去查原型的原型……一直查到
Obejct
,如果還是沒有,就報undefined
。這過程稱爲委託 (這就像一條鏈一樣,所以稱爲原型鏈) - 動態:如果在原型中增加一個屬性,它立刻對所有基於該原型的對象可見
枚舉
for in 可以用來遍歷一個對象中的所有
屬性名
過濾原型屬性,可以用
hasOwnProperty()
if (typeof one_obejct.hasOwnProperty(name)) { …… }
過濾函數,可以用
typeof
if (typeof one_obejct[name] !== 'function') { …… }
for in 是不保證順序的,如果想保證順序,可以另創建一個數組包含需要的屬性名,用簡單的for循環
刪除
delete
可以刪除對象的屬性,不會觸及原型鏈中的任何對象- 刪除對象屬性後,原型鏈的屬性會透現出來
減少全局污染
最小化使用全局變量的方法之一是爲你的應用只創建一個唯一的全局變量:
var MYAPP = {};
把這個MYAPP
作爲你的應用容器
MYAPP.person = {
firstName = 'Joe',
lastName= 'Howard'
}
MYAPP.enrollment = function(){
……
}
另一種方法減少全局變量污染的是閉包