對以前看
《JavaScript高級程序設計》
時沒有注意到的一些知識點,結合本書作以補充正則表達式
註釋數組
源於PL/I的/* */
型既能夠出如今字符串字面量
中,也可能出如今正則表達式字面量
中,如緩存
/* var a = /a*/.match(s); */
故通常建議使用//
型註釋服務器
保留字網絡
語句、變量、參數、屬性名、運算符
和標記
等標識符
不容許使用保留字,此外在對象字面量中,或用點運算提取對象屬性時,也都不能用保留字作屬性名
閉包
數字app
JavaScript只有一種數字類型,即64位
浮點數異步
字符串函數
1.JavaScript中全部的字符都是16位
的
2.轉義字符\
能夠將反斜線
,引號
,和控制字
符等不被容許的字符插入到字符串中
3.\u
用來約定指定數字字符編碼"A"==="\u0041"
4.字符串一旦被建立就沒法被改變,只能經過+
等操做符建立新字符串優化
語句
1.JavaScript中的代碼塊{}
不會建立新的做用域,故變量應該定義在函數的頭部,而不是代碼塊中
2.被當作假的值false
,null
,' '
,0
,NaN
3.JavaScript不容許在return
關鍵字和表達式之間換行,也不容許在break
關鍵字和標籤之間換行
定義
JavaCript中的對象是可變
的鍵控
集合,是屬性的容器,屬性名能夠是包括空字符串
在內的任意字符串,屬性值是除undefined
值以外的任何值
對象字面量
一個對象字面量就是包圍在一對花括號中的零個或多個名/值
對,其中若 屬性
是合法的JavaScript標識符(字母開頭,加數字、下劃線組成)且不是保留字,則並不強制要求加引號
對象值得檢索
屬性名爲非合法的JavaScript標識符,需用[]
來讀值,爲合法的標識符且不是保留字,則也能夠用.
來讀值,一般更傾向於.
,由於其效率更高更緊湊,嘗試從undefined
的成員屬性中讀值會致使TypeError
異常,如
flight.equipment // undefined flight.equipment.model // throw "TypeErrpr"
引用
對象經過引用傳遞,不會被傳遞,換句話說var a = {}; b = a;
b則和a指向同一塊內存
原型
何爲委託
?沿原型鏈查找的過程就是委託(ps:原型鏈的末端是Object.prototype)
反射
獲取對象上的屬性而不要原型中的屬性,使用hasOwnProperty()
檢查,若爲對象實例上的屬性,則會返回true
枚舉
for in
可用來遍歷一個對象上的全部屬性名(包括實例和原型),但需注意的是for in
遍歷出來的屬性是無序的
刪除
delete
沒法刪除原型中的屬性
減小全局變量污染
措施:聲明一個全局變量
,做爲命名空間
,而後將應用資源都放到這個命名空間中,能夠有效的減小與其餘程序,組件,類庫的衝突
函數對象
Js中函數就是對象,鏈接到Function.prototype
上,而Function.prototype
則鏈接到Object.prototype
上
函數字面量
函數字面量包含如下4
個部分:保留字
:function函數名
:可省略,此外函數還能夠經過函數名來進行遞歸調用形參
:函數中的形參不會被如普通變量同樣被初始化爲undefined
,而是在函數被調用的時候被初始化爲實參所提供的值語句
:包圍在花括號中的一組語句被稱爲函數的主體
調用
在一個函數中調用另外一個函數,會暫停對當前函數的執行,並將控制權和參數傳遞給新函數,此外每一個函數還會接收兩個附加參數this
和arguments
(其中this
的值取決於函數的調用模式)
函數的調用模式主要存在如下4
種:
1.方法調用模式:函數被保存爲一個對象的屬性時,當此函數被調用時this
即指向該對象
2.函數調用模式:當函數並不是對象的屬性,就被當作一個函數調用時,this
會被綁定到全局對象上,但這種設計在實際開發中會形成不少的不便,所以咱們常會再聲明一個變量並將其賦值爲this
,以下:
var obj = {name:'aleen'}; obj.sayName = function(){ var that = this; var say = function(){ alert(that.name); } say(); } obj.sayName();
3.構造器調用模式:使用new調用構造函數時,會建立一個鏈接到構造函數prototype成員的新對象,並將函數中的this
綁定到新對象上
4.Apply調用模式:由於Js中的函數也是對象,因此函數也擁有方法,任何函數在調用時使用Apply方法,能夠改變函數運行時this
的運行對象(apply的第二個參數可傳入一個參數數組
)
var obj = {age:21}; var sayName = function(){alert(this.age)} sayName.apply(obj);
參數
arguments
:在函數內部能夠經過該變量訪問全部在函數運行時傳遞給函數的實參(包括沒有被形參接收的參數),可是注意arguments
只是一個類數組的對象,擁有length屬性,但並無任何數組方法
返回
一個函數總會返回一個值,若是沒指定值,則返回undefined
,注意當函數在調用時前面加上了new
而且返回值不是一個對象,則返回新對象即this
異常處理
Js中可用throw
來拋出異常
isNum = function(num){ if(typeof num != 'number'){ throw { name:'type error', message:'there needs a number' } } } try{ isNum('a'); }catch(e){ document.writeln(e.name+';'+e.message); }
擴充類型的功能
即便用prototype
在原型上擴充實例能夠共享的方法,但有一點需注意的是——基本類型的原型是公用結構,因此在類庫混用時需當心使用,保險的作法是隻在肯定沒有改方法時再添加它
遞歸
注意一些語言爲尾遞歸提供了優化,能夠顯著提升速度,但Js並無提供尾遞歸的優化,深度遞歸可能會由於堆棧溢出而運行失敗
尾遞歸示例:
var factorial = function factorial(i,a){ a = a||1; if(i<2){ return a; } return factorial(i-1,a*i); }; console.log(factorial(4));
做用域
沒有塊級做用域(ES6中已有塊級做用域了),故最好在函數頂部聲明全部函數體中可能用到的變量
閉包
一個函數能夠訪問它被建立時的上下文環境,即成爲閉包
此外:要避免在循環中建立函數
回調
回調函數是異步處理的,故不會由於網絡傳輸或服務器響應慢而致使客戶端出現假死狀態
模塊
簡而言之:模塊是一個提供接口卻隱藏狀態和實現的函數或對象
通常形式:定義一個擁有私有變量和特權函數(特權函數利用閉包特性能夠訪問私有變量)的函數,最後返回這個特權函數或者將其保存到一個可訪問到的地方
級聯
級聯使得咱們能夠單獨在一條語句中依次調用同一個對象的不少方法
柯里化
簡單來講,柯里化就是將函數與傳遞給它的參數相結合產生新的函數的過程
function add(a,b){ return a+b; } Function.prototype.curry = function(){ var slice = Array.prototype.slice, args = slice.apply(arguments), that = this; return function(){ return that.apply(null,args.concat(slice.apply(arguments))); }; } var add1 = add.curry(1); console.log(add1(6));
記憶
例如斐波那契
var fibonacci = function(n){ return n < 2 ? n : fibonacci(n-1)+fibonacci(n-1) }
頻繁遞歸調用會消耗極大的資源,所以能夠採用記憶策略,將已經計算過的值緩存起來
var fibonacci = function(){ var meno = [0,1]; var lib = function(n){ var result = meno[n]; if(typeof result !== 'number'){ result = fib(n-1)+fib(n-2); meno[n]=result; } return result; } return fib; }();
JavaScript中的數組是一種相似於數組的對象,它將數組的下標轉變成字符串
,並用其做爲屬性
數組字面量
數組字面量var num = [1,2,3];
和對象字面量var num_obj = {'0':1,'1':2,'2',3}
基本一致都是包含3個屬性的對象,但它們的原型不一樣,num
的原型是Array.prototype
而num_obj
的原型是Object.prototype
,故 num
有length
屬性而num_obj
沒有
ps
:不一樣於強類型的語言,Js中的數組元素能夠是不一樣類型的值
長度
1.Js中的length
屬性是沒有上界的,當使用大於或等於length
的位置來存儲元素時,不會發生數組越界錯誤,而會自動增長length
的值以容納新元素
2.length
屬性的值不必定等於數組裏的屬性個數,如
myArray[100]=true; myArray.length //101 //數組中只包含一個屬性
3.[]
下標運算符會將所含表達式轉換爲一個字符串
,當表達式有`toString
方法時,就使用該方法的值
4.JavaScript中的數組下標必須是大於等於0並小於等於2的32次方-1的整數
5.設置更大的length
不會給數組分配更多的空間,而把length
設小將會致使全部下標大於等於新length
的屬性會被刪除
刪除
由於數組也是對象,因此能夠用delete來刪除數組中的元素,但它只會將那塊的值移除掉,而保留那塊的空間,故那塊的值就變成undefined
了,所以經常使用splice
方法來刪除元素,但此方法的特色在 刪除元素時是將被刪除的元素以後的元素所有移除,再不斷添加到新位置,這種作法對於大型數組來講效率不高
枚舉
數組可用for in
來枚舉元素,但它不會保證數組元素的順序,所以咱們經常使用在枚舉時咱們經常使用for
循環
數組和對象的判斷
因爲在Js中,數組和對象極易混淆,因此一個較好的判斷其類型的方法是:
var is_Array = function (value){ return Object.prototype.toString.apply(value).slice(8,-1) === 'Array'; }
指定初始值
Js不會給數組元素預設初值,[]
獲得的新數組爲空,訪問一個不存在的元素則是undefined
1.代碼塊內容和對象字面量縮進4個空格
2.if和()之間放置一個空格
3.每一個逗號和冒號後面都使用一個空格
4.在if和while這樣的結構化語句裏,始終使用代碼塊
5.將{放在一行的結尾,而不是第二行的開頭
6.儘可能使程序具有自我說明,並添加必要註釋,推薦行註釋
7.儘可能在每一個函數開始的地方,聲明全部變量
8.避免switch語句塊的條件穿越到下一條case
全局變量
代碼塊中沒有塊級做用域
自動插入分號,故應該在將{放在上一行的尾部,而不是下一行的頭部
保留字,Js中的保留字不能用來作變量名和參數,當保留字被用做對象字面量的鍵值時,必須用''
括起來,並用[]
引用