1.六種數據類型
5種基礎的:Undefined,Null,Boolean,Number,String(其中Undefined派生自Null)
1種復雜的:Object(本質是一組無序鍵值對)
2.字符串轉數字
-
Number(str):先求值再轉換(先valueOf再toString都不行就是NaN),一般與我們的預期結果不一樣,比如Number(”)=Number(false)=Number(null)=0而var x;Number(x)=NaN。。。所以一般都用下面兩種方式
-
parseInt(str):可以指定進制,建議使用parseInt(x, 10);這樣的格式,即始終指明進制
-
parseFloat(str):不可以指定進制,解析整數時返回整數而不是浮點數
3.獲取字符串長度
String類型的值都有length屬性。str.length返回串長整數值,而不是通過其它函數來獲取串長
4.值傳遞與地址傳遞
函數傳參都是值傳遞
5.作用域鏈
本質是一個棧,存放了各層的變量對象(類似於編譯器的符號表指針棧),變量對象持有該層所有變量和函數的訪問權限,如果該層是函數,那么變量對象是arguments對象,棧頂是正在執行的上下文環境對應的變量對象,棧底是全局執行環境對應的變量對象。
6.作用域
沒有塊級作用域,有函數作用域
7.創建Object對象的2種方法
- var obj = new Object();obj.attr = value;
傳統的方式,調用構造函數創建對象
- var obj = {attr1 : value1, attr2 : value2}或者var obj = {“attr1″ : value1, “attr2″ : value2}
對象字面量表示法,屬性名可以是字符串
注意:
-
除非屬性名有歧義例如:null, var等等,一般不要用字符串做屬性名,當然只是習慣約束
-
用對象字面量方式定義對象時,不會調用其構造函數
8.訪問屬性值的兩種方法
-
obj.attr
-
obj[“attr”] 優點是可以通過變量來訪問屬性,如var attrName = “attr”;obj[attrName]更靈活
9.數組的聲明與初始化
-
var arr = new Array(value1, value2...);
-
var arr = Array(...);可以省略new
-
數組字面量:var arr = [value1, value2...];
注意:用數組字面量定義數組時也不會調用其構造函數
10.數組相關函數
見附錄
11.函數聲明與函數表達式的區別
-
function fun(){...} js引擎會在加載源代碼時生成該函數對象
-
var fun = function(){...} js引擎在執行時才會生成該函數對象
12.函數重載
不支持重載。后聲明的函數會覆蓋先聲明的,本質是對函數名進行了多次賦值操作(函數名只是一個指針變量)
13.函數內部特殊屬性
-
arguments.callee 函數指針,指向擁有該arguments對象的函數,即當前函數
-
this 當前執行環境的引用,頂層的this就是window
-
arguments.callee.caller 函數指針,指向調用當前函數的函數,沒有則返回null
注意:this可以是對象引用或者函數引用,但callee和caller只能是函數引用
14.函數對象的屬性和方法
-
length 函數期望的命名參數的個數,js中可以給函數傳遞任意多個參數,因為除了形參,還可以用arguments獲取任一參數
-
prototype 指向函數的原型對象
-
call(context, arg1, arg2...) 用來在特定的作用域中調用函數,解除對象與函數的緊耦合
-
apply(context, arguments或其它數組對象) 功能同上,支持數組參數
-
bind/unbind(context, arg1, arg2...) 綁定/解綁執行環境或參數,可以從已有函數生成新函數,但用bind連續綁定是無效的(連續 != 多次),例如:
function fun(){ alert(this.data); } var obj = { data : 'obj_data' }; var newObj = { data : 'new_obj_data' }; fun1 = fun.bind(obj); fun1(); fun2 = fun1.bind(newObj);//連續綁定 fun2(); fun3 = fun.bind(newObj);//多次綁定 fun3();
以上代碼輸出’objdata’, ‘objdata’, ‘newobjdata’,第二次綁定失敗了,因為bind函數內部是用call來實現的,連續綁定的效果類似於:
//第一次綁定得到的函數 fun1 = fun.call(obj); //第二次綁定得到的函數 fun2 = fun1.call(newObj);
第二次綁定得到的函數中fun1內部的this確實指向newObj,但fun1中根本沒有用到this,所以沒有任何影響
15.一些常識
-
this永遠指向自身所屬的對象(你是誰的屬性,你內部的this就是誰)
var obj1 = { data : 1, fun : function(){ alert(this.data); } }; var obj2 = { data : 2 }; obj1.fun(); obj2.fun = obj1.fun; obj2.fun();
以上代碼輸出1和2,因為執行過倒數第二句后,obj2新增了一個fun屬性,值為obj1.fun的引用,但因為obj2.fun是obj2的屬性,所以this指向obj2
-
盡量在構造函數原型上定義成員函數,因為直接在構造函數中定義的函數有運行時閉包的開銷
-
在js中應該用單引號,因為JSON和XML里只有雙引號,用單引號可以避免轉義
-
盡量在變量聲明的同時初始化,以便區分undefined表示未聲明。因為對已聲明但未初始化的變量和未聲明的變量用typeof操作符都會返回”undefined”
-
NaN(Not a Number)與任何值都不相等,包括NaN本身,所以需要用isNaN()函數來判斷
-
只能給引用類型的值動態地添加屬性。給基本類型的值添加屬性不會報錯但沒有任何意義
-
數組會根據索引自動增長。需要注意length屬性是可寫的,也就是說可以動態地設置數組長度,如截掉尾部元素
-
函數名只是一個指針變量。function fun{...} fun = null;只是斷開了引用關系,函數體並沒有被銷毀
附錄
1.基礎數據類型
-
Undefined 已定義但未初始化的對象的默認值
-
Null 表示一個空對象指針,所以用typeof檢測之返回object
-
Boolean 布爾值,注意Boolean()轉換函數,規則如下:
-
true/false ~ 不變
-
非空字符串/空字符串 ~ true/false
-
非0數字/0和NaN ~ true/false
-
任何對象/null ~ true/ false
-
undefined ~ false
上面這些規則非常重要,因為if條件會自動應用Boolean()轉換,而且if(obj)是在js代碼中是很常見的,很多時候流程控制錯誤都是if條件自動轉換造成的
-
-
Number 數值,js中+0和-0相等,注意NaN,它與任何東西都不相等,包括自身,而且它既不大於n也不小於等於n。Number變量支持toString()函數,可以用來對數值串進行進制轉換,例如var num = 17;num.toString(16)返回”11″
-
String 字符串,注意字符串的不可變性,進行巨量拼接操作時應該用數組 + join而不是循環+
2.Object類型變量的屬性和方法
-
Constructor 保存這構造函數的引用
-
hasOwnProperty(porpertyName) 用來檢查當前對象是否擁有指定屬性(此處”屬性“包括屬性和方法)
-
isPrototypeOf(obj) 用來當前對象是不是指定對象的原型
-
propertyIsEnumerable(propertyName) 用來檢測指定屬性是否可枚舉
-
toLocaleString() 相當於toString()函數,但附加了地區特征
-
toString() 返回對象的字符串表示
-
valueOf() 返回對象的字符串、數值或布爾值表示
3.常見引用類型
-
Function js中函數也是對象,非常靈活,例如:
var load = window.onload; window.onload = function(){ //do something load();//就是這么簡單,添一對括號馬上執行 }
-
Array 數組類型的操作函數是最多的
-
棧方函數:push() 在數組末尾插一項, pop() 尾元出棧
-
隊列函數:push() 同上,shift() 首元出隊並返回首元;反向隊列(隊頭進,隊尾出)unshift()/pop()
-
排序函數:sort(fun) 無參比較字符串升序排列,有璨傳入自定義比較函數返回正值/負值/0;reverse() 反轉順序
注意:sort()/reverse()都會直接改變原數組,而且sort()默認實現方式不太科學,對[1, 3, 10, 5]排序的結果是[1, 10, 3, 5],想要心里想的結果,必須傳入自定義比較函數
-
操作函數:
-
arr.concat(arr1, arr2...) 連接形成新數組
-
arr.slice() 相當於substring對字符串的截取效果,用法也一樣
-
arr.splice() 向數組中部插入項,splice(startIndex, num, item1, item2...) 表示把從startIndex開始的num項替換為各個item,只有前兩個參數表示把從startIndex開始的num項換為空(也就是刪除),用splice可以實現刪除/替換/插入操作。
注意:splice函數也會直接改變原數組。
-
-
位置函數:indexOf(value)和lastIndexOf(value),查找value的索引位置,沒找到返回-1,內部用的是全等操作符(===)
-
迭代函數:every(), filter(), forEach(), map(), some()都是對數組中的每一項運行指定方法,IE9+支持且並不常用,在此不展開敘述
-
歸約函數:reduce(), reduceRight() 不做介紹,原因同上
-
-
Date類型:相關內容略多,參見W3School
-
RegExp類型:var regex = /^cat$/i;創建正則表達式(RegExp類型),支持的模式有g, i, m分別表示全局模式,忽略大小寫模式,多行模式。當然,也可以用new RegExp(strRegex, strMode),不過,有什么理由非要去用這種方式呢?
js支持正則捕獲,var matches = regex.exec(text); 通過matches[0], matches[1]...來獲取捕獲到的內容
普通的正則匹配:regex.test(text)返回true/false
-
基本包裝類型:Boolean,String和Number,一直都在見面,只是沒有注意到,例如:
var str = 'smilestome'; var str_ = str.substring(1);
以上代碼等價於:
var s1 = new String('smilestome');//創建包裝類型實例 var s2 = s1.substring(1);//在實例上調用相應方法 s1 = null;//銷毀實例
自動裝箱拆箱,為了讓基礎數據類型用起來更方便,但需要注意:new String()與String()轉換方法不同,前者返回object類型,而后者返回string類型,鑒於這樣的區別,混用會引起不必要的麻煩,所以我們沒有理由顯式創建包裝類型。Boolean,Number與之類似。