javascript學習總結
1 運算符與表達式:
運算符:
包裝對象:數值,字符串,布爾值在給增加屬性時會自動創建一個臨時對象,即包裝對象,而包裝對象是只讀的,其增加的屬性并不會保存下
來。可以通過String(),Number(),Boolean()構造函數顯示創造包裝對象。對數值,字符串,布爾值調用方法時也會自動創建一個臨時對象,即包裝對
象,在用完后會自動銷毀。
----undefined,null,布爾值,數值,字符串比較的是值。兩個單獨的對象或數組永不相等。因為對象和數組比較的是引用,其他比較的是值。
----
== 在判斷兩個值是否相等時可以做類型轉換,而 === 在判斷時不做類型轉換。假值是false,null,undefined,0,-0,NaN,"",所有的其他值包括所有對象都是真值。
----
全局對象:
全局屬性(比如undefined,Infinity和NaN),
全局函數(比如:isNaN(), parseInt(), eval()),
構造函數:(比如:Date(), RegExp(), String(), Object(), Array()),
全局對象:(比如:Math和JSON)
----在全局作用域下聲明變量可以不寫 var,但聲明局部變量(在函數體內)則必須使用var語句,否則,將會當作全局變量處理。使用var聲明的變
量是不可刪除的,而未聲明的變量賦值創建的全局變量是可以刪除的。
----聲明提前:javascript函數體內聲明的所有變量(但不涉及賦值)都被“提前”至函數體的頂部,變量在聲明之前已經可用。
常用運算符:
in運算符:in運算符希望它的左操作數是一個字符串或可以轉換為字符串,希望它的右操作數是一個對象。如果右側的對象擁有一個名為左操作
數的屬性名,那么表達式返回true。
instanceof運算符:instanceof運算符希望左操作數是一個對象,右操作數標識對象的類。如果左側的對象是右側類的實例,則表達式返回
true,否則返回false,如果
instanceof左操作數不是對象,返回false,如果右操作數不是函數,則拋出類型錯誤異常。
typeof運算符:返回操作數的類型:undefined:“undefined”,null:"object",true或false:"boolean",任意數字或NaN:"number",任意字符
串:“string”,任意函數:“function”,任意內置對象(非函數):“object”,任意宿主對象:由編譯器各自實現的字符串,但不
是“undefined”,“boolean”,“number”,“string”
delete運算符:刪除對象的屬性或者數組元素。用它來做刪除操作的,不是用來返回一個值的。用戶通過var聲明的屬性不能刪除。用戶通過
function語句定義的函數和函數參數也是不能刪除的。但可以刪除其屬性和元素。
void運算符:出現在操作數之前,操作數會照常計算,但忽略計算結果并返回undefined。
函數聲明語句和函數定義表達式:
1函數聲明語句: var f = function fact(x){return x+1;}//函數的名稱(可省略)可用于函數的遞歸調用。
2函數定義表達式: function f(x){return x+1;}//適用于在賦值和調用過程中的函數定義,(如果有名稱:將稱為定義該函數的函數內部
的一個局部變量。)通常不需要名稱,適合用來定義只會用到一次的函數。
函數聲明和定義語句通常出現在js代碼的最頂層,也可以嵌套在其他函數體內,但在嵌套時,函數聲明只能出現在所嵌套函數
的頂部,也就是說,函數定義不能出現在if語句,while語句或其他任何語句中。
這兩種聲明方式的區別:
函數聲明(語句)通過var = function(不能加函數名,否則不能提前。):和通過var聲明變量一樣,只有變量聲明提前了,變量
的初始化代碼仍然在原來的位置。
然而通過var聲明函數的話,函數名稱和函數體均提前了。不能出現在循環,條件判斷,try/catch/finally以及with語句中。函數定義
(表達式):不會被提前。可以出現在任何地方。
語句:
for/in語句:for(variable in object) statement :遍歷一個對象的屬性。將對象object中的各個屬性名賦值給變量variable,如果
是數組則遍歷索引。內置的方法是不可遍
歷的。自定義的方法和屬性是可遍歷的。通過繼承獲得的屬性也是可遍歷的。
with語句:with(object)statement 將object所表示的對象當成statement語句的作用域,然后執行statement,最后把作用域
鏈恢復到原始狀態。
----
3 對象:
概念:屬性的無序集合,每個屬性都是一個名/值對,除了可以保持自有的屬性,javascript對象還可以從一個稱為原型的對象
繼承屬性。除了字符串,數字,true,false,null,undefined(和不可變對象非常相似),其他的值都是對象。
三類對象:
內置對象:是由ECMAScript規范定義的對象或類。例如:數組,函數,日期,正則表達式。
宿主對象:是由javascript解釋器所嵌入的宿主環境(比如web瀏覽器)定義的。
自定義對象:是由運行時的javascript代碼創建的對象。
兩類屬性:
自有屬性:是直接在對象中定義的屬性。
繼承屬性:是在對象的原型中定義的屬性。f.prototype = p (p是一個對象,f構造函數繼承了p的屬性和方法。通過new
f()可以創建f的對象。)
對象的創建:可以通過對象直接量,關鍵字new,Object.create()函數來創建對象。
對象直接量:由若干個名值對組成的映射表,名值對之間用逗號分隔,名和值用冒號分隔,外面用花括號括起來。屬性值可以
是任意類型的javascript表達式,表達式的值,(可以是原始值,也可以是對象的屬性的值)。所有通過對象直接量創建的對象都具有同一個原型對
象,可以通過Object.prototype獲得對原型對象的引用
new創建對象:new運算符創建并初始化一個新對象,關鍵字new后跟一個構造函數,構造函數用以初始化一個新創建的對
象,原始類型(如:Object({}),Date,Array([]),RegExp)都包含內置的構造函數。用戶自定義的構造函數來初始化對象也是非常
常見的。通過new和構造函數創建的對象的原型是構造函數的prototype屬性的值。
原型:沒有原型的對象為數不多,Object.prototype,其他原型對象都是普通對象,普通對象 都具有原(Object.prototype),
創建對象:Object.create(),可以通過任意原型創建新對象。第一個參數是對象的原型,第二個參數可選對對象的屬性的描述。如:
var o1= Object.create({x:1,y:3});
var o2= Object.create(null)=>>不繼承任何屬性和方法
var o3= Object.create(Object.prototype);==>和new Object()和{}一樣。
屬性的查詢與設置:
查詢:如:var author = book.author;//得到book的“author”屬性。 也可以:var author = book["author"];
設置:如:book.edition = 5;
兩者的區別:(.)操作符使用靜態的標識符,必須寫死在程序中。而([])使用動態的字符串值,可以在運行是更改。如果對
象已有屬性,則改變這個已有的屬性,如果不存在這個屬性,則對象增加這個屬性,如果繼承,則被同名的屬性覆蓋。
繼承:假設要查找對象o的屬性,如果o中不存在,會在o的原型對象中查詢屬性,如果還沒有,會在這個原型對象的原型中查
找,直到找到屬性或者原型為null的對象為止。這就是原型鏈。通過這個鏈實現屬性的繼承。通過方法var c= inherit(對象變量a或對
象);可使c對象繼承a對象的屬性和方法,注:它總是在原始對象上創建屬性或對已有的屬性賦值,而不會去修改原型鏈上的屬性,
只有在查詢屬性時才會去原型鏈上查找,而設置屬性與繼承無關。
刪除屬性:delete運算符可以刪除對象的屬性。它的操作數應當是一個屬性訪問表達式。如:delete book["main title"];只能刪
除自有屬性,不能刪除繼承屬性。要刪除繼承屬性必須從定義這個屬性的原型對象上刪除它。
檢測屬性:in操作副:in操作副左側是屬性名,右側是對象。 對象的hasOwnProperty()方法用來檢測給定的名字是否是對象的
自有屬性,如:o.hasOwnProperty("x");//檢測對象o的x屬性是否是自有屬性。 propertyIsEnumerable()方法只有檢測到是自有屬性且
這個屬性的可枚舉性為true時才返回true。 還可以使用(!==)判斷一個屬性是否是undefined。
枚舉屬性:for/in循環可以在循環體中遍歷對象中的所有可枚舉屬性(包括自有屬性和繼承屬性)。把屬性名稱賦值給循環變
量。對象繼承的內置方法是不可枚舉的。 Object.keys():返回一個數組,這個數組由對象中的可枚舉的自有屬性的名稱組成。
Object.getOwnPropertyNames():返回對象的所有自有屬性的名稱,而不僅僅是可枚舉的屬性。
存儲器屬性:由getter和setter定義的屬性。getter屬性返回屬性存取表達式的值,setter負責設置數據屬性的值。和數據屬性不
同,存儲器屬性不具有可寫性。存儲器屬性可以繼承。
屬性的特征:即可寫,可枚舉和可配置的特性。
對象的三個屬性:
原型屬性:是用來繼承屬性的,原型對象在實例創建之初就建立好了。將對象作為參數傳入Object(原型對
象).getPrototypeOf(對象)可以查詢它的的原型。對象可以使用o.constructor.prototype來檢測一個對象的原型。通過new表達式創建
的對象,通常繼承一個constructor屬性,這個屬性指代創建這個對象的構造函數。對于用Object。create()創建的對象的
constructor.prototype都是Object()的構造函數。
_proto_屬性:用以直接查詢/設置對象的原型,但不推薦使用,因為很多瀏覽器不支持。
類屬性:是一個字符串,用以表示對象的類型信息。沒有設置這個屬性的方法,只有間接的查詢它。默認的toString()返
回如下形式的字符串:[object class](繼承自Object),可以如下獲得類的字符串:Object.prototype.toString.call(o).slice(8,-1);對象直接
量,Object.create和自定義傳見的對象的類屬性都是Object。
可擴展性:表示是否可以給對象增加新屬性,所有的內置對象和自定義對象都是可擴展的,函數Object.esExtensible()
來判斷該對象是否是可擴展的。可以用函數:Object.preventExtensions()將對象轉換為不可擴展的,一旦轉換為不可擴展,就無法轉
換為可擴展的。
4 數組:
創建數組:
數組直接量:在方括號中將數組元素用逗號隔開即可,值不一定是直接量,也可以是任意的表達式。也可以包含對象直接
量或其他數組直接量。如果省略某個值,省略的元素將被賦予undefined
構造函數:
1調用時沒有參數,如:var a=new Array();等同于([])
2調用時指定長度,如:var a=new Array(10); 顯式指定兩個或多個數組元素或數組的一個非數值元素,如:var
a=new Array(3,2,4,"testing","testing");
數組元素的讀和寫:所有的數組都是對象,可以為其創建任意名字的屬性,當數組使用非負整數(可以經過類型轉換成非負整
數)時,屬性名將當成索引對待,效率變高。如果使用的屬性是索引,數組將維護其length屬性值。當查詢不存在的屬性會得到
undefined,
稀疏數組:包含從0開始的不連續索引的數組。length屬性值大于元素的個數。在數組直接量中省略值不會創建稀疏數組,省
略元素其值存在定義為undefined,只能通過如下方式創建:
1 var a=new Array(5);
2 var a=p[];a[1000]=0; 3 var a=[,];
length屬性:
一。如果為一個數組元素賦值,它的索引i大于或等于現有數組的長度,length屬性的值將設置為i+1.
二。設置length屬性為一個小于當前長度的非負整數n時,大于或等于n的元素將從中刪除。將length設置為大于當前長
度,不會向數組增加新元素,只是創建一個空的區域。
數組元素的增加和刪除:
為新索引賦值,如:var a=[];a[0]="zero";
push()方法:可以在數組末尾增加一個或多個元素。
使用unshify()方法向數組首部插入一個元素,其他元素依次下一位置。
刪除:
delete運算符:如:delete a[2];不影響數組長度。 可以設置length屬性截斷數組。
pop方法:減少長度1并返回被刪除的元素。
shift()從頭部刪除一個元素,各索引減1.
數組遍歷:
1for循環
2for/in:循環每次將一個可枚舉的屬性名(包括數組索引)賦值給循環變量,不存在的索引不會遍歷到。還會遍歷到從
Array.prototype中繼承來的方法。
forEach():按照索引的順序按個傳遞給定義的一個函數,如:數組對象.forEach(function(數組元素){元素操作;})
多維數組:用數組的數組來近似。訪問數組的數組中的元素:使用兩次([]),如:table[row][col]
數組方法:在Array.prototype中定義的操作數組的函數。在Array構造函數上定義了這些方法的靜態函數版本,所以可以用
Array.方法名(數組對象,方法參數);調用方法。
或:Array.prototype.方法名.call(調用方法的對象,方法參數);
數組對象.join():將數組中所有元素轉換為字符串并鏈接在一起,有一個可選的參數來分隔各個元素,默認為(,)。
數組對象.reverse():將原先數組逆序轉換數組,不創建新數組。
數組對象.sort():將數組中的元素排序并返回排序后的數組。默認按字母表順序排序。如果包含undefined,排到數組尾
部。可傳入一個函數進行比較。
數組對象.concat():連接數組對象的元素和參數對象中的元素或數組元素。
數組對象.slice():返回數組對象的一個子數組,兩個參數分別指定新數組起始和結束的索引位置。
數組對象.splice():會修改原始數組,在插入或刪除元素后會根據需要增加或減少數組的索引值。第一個參數指定了插入
和刪除的起始位置,第二個參數指定了應該
從數組中刪除元素的個數(省略則刪除起始到結束的額所有元素),返回由刪除元素組成的數組,緊隨其后的任意個數的參數指定了需
要插入到數組中的元素。
數組對象.push():將數組當作棧使用,push()在數組尾部增加一個或多個元素返回新數組長度。
數組對象.pop():刪除數組最后一個元素,減少數組長度并返回它刪除的值,
數組對象.unshift():在頭部插入一個或多個元素,并將已存在的元素移動到更高索引位置,返回數組新的長度
數組對象.shift():刪除第一個元素并將其返回。隨后元素下移一個位置。
數組對象.toString()或tolocaleString:將每個元素轉換為字符串,并用逗號分隔字符串列表,不輸出方括號。ECMAScript5中的數組方法:
大多數方法第一個參數接受一個函數,并對數組的每個元素調用一次該函數。稀疏數組中不存在的元素不調用。調用函數提供3個參數:數
組元素,元素索引,數組本身,通常后兩個參數可以忽略。如果數組方法有第二個參數,一般數組方法的第一個參數(即函數)作為第二個參數的this
使用。
數組對象.forEach():為每個元素調用指定的函數,傳遞的函數作為forEach的第一個參數,函數有3個參數,后兩個可忽略。
數組對象.map():將調用數組的每個元素傳遞給指定的函數,并返回一個數組,它包含該函數的返回值。返回新數組,不修改調用的數組,
數組對象.filter():返回的數組元素是調用的數組的一個子數組,傳遞的函數用來邏輯判斷,返回true或false,如果返回true,則該元素為返
回子數組的成員。filter()會跳過稀疏數組中缺少的元素,返回的數組總是稠密的。
數組對象.every():(所有元素都滿足返回true)對數組的邏輯判定,對數組元素應用指定的函數進行判定,返回true或false,當且僅當數組
中所有元素調用判定函數都返回true,它才返回true。
數組對象.some():(存在元素滿足返回true)至少有一個元素調用判定函數返回true,就返回true,空數組上erery返回true,some返回
false。
數組對象.reduce():使用指定函數將數組元素進行組合,返回單個值,傳遞的函數有二個參數,分別指調用的元素的值和reduce()方法的
第二參數的初始值,第二個參數(可選)是傳遞給函數的初始值。當不指定初始值時將使用數組的第一個元素作為初始值。
數組對象.reduceRight():和reduce()工作原理相同,按照索引從高到低處理數組。
數組對象.indexOf():搜索整個數組具有給定值的元素,返回找到的第一個元素的索引,沒有找到就返回-1。第二個參數指定從數組開始搜
索位置的索引。
數組對象.lastIndexOf():反向搜索。
判斷是否為數組:Array.isArray(需要判斷的未知對象)
作為數組的字符串:數組可以使用charAt() 和([])訪問單個字符,但typeof操作符返回string,Array.isArray()返回false。通用的數組方法可以
應用到字符串上(修改原數組的方法除外,因為字符串是只讀的),如下調用:Array.prototype.方法名(字符串對象,方法參數);
5 函數:
概念:只定義一次,可以被執行或調用任意次,函數定義包括型參,函數調用提供實參。函數使用實參的值計算返回值,稱為該函數調用表達式
的值。
this:指代調用該函數的上下文(調用方法的對象)。
方法:函數作為對象的一個屬性。構造函數用于初始化一個新的對象。
函數就是對象:可以吧函數賦值給變量,作為參數傳遞給其他函數,可以設置屬性,調用它們的方法。(所有的這一切都可以在對象上完
成。)。可以嵌套定義函數形成閉包,就可以訪問父函數中的任意變量。
return語句:如果函數不包含return,或return不包含與之相關的表達式則返回undefined值。
作為函數:如下方式調用:函數名(實參列表),如:printprops({x:1}); 這種方式的調用在嚴格模式下this指undefined。而非嚴格模式為全局
對象,所以這種方式調用函數的函數一般不使用this。
作為方法:如果對象o的m方法定義為一個函數,如:o.m=f;則可以如下調用:o.m(x,y);(或o["m"](x,y); a[0](z)//假設數組a[0]是一個函數)
調用上下文為o對象,在方法體中可以使用this引用。函數將基于一個對象進行操作。
作為構造函數:如:var o =new Object();與var o=new Object;等價(無參時可以省略括號)。 構造函數可以使用this來引用這個新創建的
對象。構造函數通常不使用return,只為了初始化新對象,如果顯示返回一個對象,則使用返回的對象,其他情況都返回新創建的對象。
通過它們的call()和apply()方法間接調用:任何函數可以作為任何對象的方法來調用,哪怕這個函數不是那個對象的方法。查看相關api。
函數的形參和實參:
形參:當調用函數的時候傳入的實參比函數聲明的形參少時,剩下的形參都設置為undefined值。
實參對象:參數對象標識符arguments(是一個類數組對象)是指向實參對象的引用,它也包含length屬性。js在省略實參都將是
undefined,多出的參數會自動省略。如果形參沒有定義,則實參可以是任意個數。
函數變量:如:var f = function square(){};或:var ff=square; 可以通過f()和square()調用這個函數對象。可以將這個函數變量用作對象的屬性,
數組的元素,其他函數的實參傳遞。
函數(變量)的屬性:函數是一個特殊的對象,可以擁有屬性,當函數需要一個靜態變量時可以定義函數屬性。如,將函數當成一個變量或一個數
組(只有在定義函數的上下文環境下給函數屬性賦初值才起效果),用于保存上次調用記錄的信息。
函數自定義屬性:通過函數名.函數變量=值;可以為函數定義變量屬性。在函數體內部和外部均可以。定義的屬性變量可以在函數體內直接調
用。
作為命名空間的函數:為了防止定義的全局變量污染全局命名空間,可使用局部函數,這樣全局變量就成了局部變量了。如:
(function(){//模塊代碼}());//定義這個函數并立即調用它。
作用域鏈:如果將局部變量看作是自定義實現對象(函數)的屬性的話,每一段全局代碼或函數,都有一個與之關聯的作用域
鏈,這個對象(作用域鏈)定義了這個作用域中的變量,這個作用域鏈是一個對象列表(這組對象定義了全局作用域中的變量)。
在訪問變量時,先查看本地作用域是否有此變量,如果沒有則依次向上一級作用域查找直到全局作用域()。每定義的函數都會在
所定義函數創建全局作用域,每次調用函數時都會在所調用函數作用域鏈上創建對象(活動對象(包含所需的形參,this,本地變量
的值))。函數定義時的作用域鏈到函數執行時依然有效。
閉包:函數對象可以通過作用域鏈相互關聯起來,函數內部的變量都可以保存在函數作用域內。外部函數將嵌套的函數對象作
為返回值的時候往往會發生這種情況,閉包。
閉包的官方定義:允許使用內部函數(即函數定義和函數表達式位于另一個函數的函數體內),而且,這些內部函數可以訪問他
們所在的外部函數中聲明的所有局部變量,參數,和聲明的其他內部函數,當其中一個這樣的內部函數在包含它們的外部函數之外
被調用時,就會形成閉包。即內部函數會在外部函數返回后執行。而當這個內部函數執行時,它仍然必須訪問其外部函數的局部變
量,參數以及其他內部函數。這些局部變量,參數和函數聲明(最初時)的值是外部函數返回時的值,但也會受到內部函數的影
響。
一個函數在每次返回時所創建的和傳入的臨時變量和參數就會被垃圾回收而不會被保存,但如果有一個外部引用指向這個函數中的
某個變量或嵌套函數(將函數的某個屬性賦值給外部變量,或返回一個嵌套函數的引用賦值給外部變量),則不會將變量綁定對象
從作用域鏈中刪除(在調用這個函數時會創建這個函數的變量綁定對象在作用域鏈中)。
每個新創建的函數對象都會創建一個新的作用域鏈和一個新的私有變量,并且彼此包含不同的私有變量。當外部函數返回,其他任
何代碼都無法訪問私有變量,只有內部的函數
才能訪問它。
閉包就是在一個外部函數中返回一個嵌套函數或一個對象的方法,嵌套函數和方法實現對外部函數定義的私有變量的修改。其
他方式無法無法修改私有變量。
函數屬性:
length屬性:即函數的形參個數(函數調用時期望傳入的實參個數):arguments.callee.length.
prototype屬性:每個函數都包含一個prototype屬性,這個屬性指向一個對象的引用,這個對象稱作原型對象,新創建的對象會從原型對象
上繼承屬性。
函數方法:
call方法:第一個參數是要調用的函數的母對象,在函數體內通過this來獲得對他的引用。第二個參數及后面的參數是就是要傳入調用函數
的實參
apply方法:和call方法功能一樣,區別:它傳入的實參都放入一個數組中,如:f.apply(o,[1,2]);
bind()方法:將函數綁定至某個對象并傳入一部分參數。在調用的時候可以傳入另一部分參數。 如:function f(y){return
this.x+y;} var o ={x:1} var g=f.bind(o); g(2); 第一個參數即被調用函數的this指針,它可以為null。
toString()方法:大部分返回函數的完整源碼。
Function()構造函數:用Function()構造函數來定義函數,如:var f=new Function("x","y","return x*y";); 與如下定義的函數等價:
var f=function(x,y){return x*y;}注:Function()構造函數除了最后一個參數代表函數體,其余都是函數的形參。都需要用“”括起來。函
數體代碼的編譯總是在全局作用域下執行。
高階函數:接受一個或多個函數作為參數,并返回一個新函數,這個新函數可以帶有參數。
不完全函數:即把一次完整的函數調用拆成多次函數調用,每次傳入的實參都是完整實參的一部分,每個拆分開的函數叫做不完全
函數,每次函數調用叫做不完全調用。每次調用都返回一個函數,知道得到最終的運行結果為止,f(1,2,3,4,5)的調用等價為f(1,2)(3,4)
(5,6),和每次調用相關的函數就是“不完全函數”。
6 類與模塊:
類和模塊:如果兩個實例都從同一個原型對象上繼承了屬性,則說他們是同一個類的實例。
類和原型:可以通過創建一個工廠函數用于創建對象,這個工廠函數定義了所要創建對象的屬性,可以在這個工廠函數的屬性
上定義原型對象(鍵值對 方法名/函數體)然后通過工廠函數創建繼承了原型對象的實例 (通過inherit(原型對象)方法)。
類和構造函數:通過同一個構造函數創建的所有對象都繼承自一個相同的原型對象(構造函數名.prototype屬性)。定義構造函數
就是定義類,構造函數首字母大寫。
類的標識:當且僅當兩個對象繼承自同一個原型對象是,它們才屬于同一個類的實例。
constructor屬性:每個javascript函數都自動擁有一個prototype屬性,這個屬性是一個對象,這個對象包含唯一一個不可枚舉
的屬性constructor,constructor屬性的值是一個原構造函數對象。每個對象都包含一個constructor屬性,它指向創建這個對象的構造函
數。預定義的原型對象包含constructor屬性,通過顯示創建的prototype對象不具有constructor屬性(必須通過自己手動添加
constructor:構造函數名)。
javascript中的java式類繼承:javascript中的構造函數對象中定義的屬性和方法是屬于某個實例的(構造函數上定義的方法通
常不使用this引用,而只對傳入的參數進行操作。),javascript中原型對象上定義的屬性和方法被所有實例所繼承(通過this引用構
造函數中定義的字段和方法)。javascript實例對象(通過new創建的對象)上定義的屬性和方法是不會被所有實例共享的。
類的擴充:基于原型的繼承機制是動態的,對象從原型繼承屬性,如果創建對象之后原型的屬性發生變化,會影響到所有繼承
這個原型的實例對象。可以通過給原型對象增加新方法來擴充javascript類。可以從所有的對象,如:數字原型Number,字符串原型
String,數組原型Array,函數原型Function對象原型Object增加方法。這樣所有的同類對象的實例會自動繼承對應的方法。
類和類型:無法用classof()函數,它只能返回javascript自定義的數據類型,所有的實例對象都返回“Object”。
instanceof運算符:如果o繼承自c.prototype,則表達式o instanceof c返回true,非直接繼承也能返回true。缺點:無法通過對象來
獲取類名,只能檢測對象是否屬于指定的類名。
isPrototypeOf()方法:檢測對象的原型鏈上是否存在某個特定的原型對象。與instanceof功能相同。原型對象.PrototypeOf(對
象);缺點:無法通過對象來獲取類名,只能檢測對象是否屬于指定的類名。
constructor屬性:可以直接獲取對象所繼承類的類名。以上3個方法在不同的框架中就無法識別。在多個執行上下文的函數檢
測的結果也不相等。但它們的名稱是一樣的。
模塊:javascript中沒有定義用以支持模塊的語言結構,很多框架都包含模塊系統,如:node.js的module.exports和require函
數,用以聲明(導出,可以導出一個構造函數的實例,即一個new創建的對象。也可以導出一個構造函數(然后在加載該模塊時再
new初始化對象)。)和加載模塊(先加載模塊,然后通過new通過命名空間來調用所需構造函數或直接使用已初始化的對象)。
7 正則表達式:
正則表達式的定義:
直接量,如:var pattern = /s$/;//包含在一對斜杠之間。用構造函數RegExp()定義:var pattern=new RegExp(“s$”);
直接量字符:所有的字母和數字都是按照字面含義進行匹配,
非字母的字符匹配:使用反斜杠作為前綴進行轉義。
直接量字符及匹配如下:
字母與數字:自身,
\o:Null字符,
\t:制表符,
\n:換行符,
\v:垂直制表符,
\f:換頁符,
\r:回車符,
\xnn:由十六進制數nn指定的拉丁字符,
\uxxxx:由十六進制數xxxx指定的unicode字符,
\cX:控制字符:^X,
許多標點符號具有特殊含義(^ $ . * + ? = ! : | / \ ( ) [ ] { }):必須使用反斜杠進行匹配,
其他標點符號沒有特殊含義:可直接進行匹配。
字符類:匹配字符類中的其中的任何一個字符(只匹配一個):
[...]:放括號內的任意字符,
[^...]:不在放括號內的任意字符,
. :除換行符和其他unicode行終止符之外的任意字符,
\w :任何ASCII字符組成的單詞等價于[a-zA-Z0-9] ,
\W:任何不是ASCII字符組成的單詞等價于[^a-zA-Z0-9],
\s:任何unicode空白符(空格符,制表符,和其他的unicode空白符),
\S:任何非unicode空白符的字符,
\d任何ASCII數字等價于[0-9],
\D:除了ASCII數字之外的任何字符等價于[^0-9],[\b]:退格直接量。
重復:
{n,m}:匹配前一項至少n次但不超過m次,
{n,}:匹配前一項n次或者多次,
{n}:匹配前一項n次,
?:匹配前一項0次或者1次,
+:匹配前一項1次或多次,
*:匹配前一項0次或多次.
非貪婪的匹配:重復中使用的匹配都是貪婪匹配(匹配重復字符是盡可能多的匹配),非貪婪的匹配只須在匹配的字符后
跟隨一個問號即可,如:"??","+?","*?"," {1,5}?",非貪婪匹配會尋找字符串中第一個可能匹配的位置,從這個位置匹配到最后。
指定選擇項:
字符(|)用于分隔供選擇的字符,選擇項的嘗試匹配次序是從左到右,直到發現了匹配項。如果左邊的匹配項匹配,
就忽略右邊的匹配項。
分組:一個用途:使用圓括號來作用,用于將處理整個括號組成的單元。“+”,"?"|"*"對單元進行處理。 另一個作用是在完整
的模式中定義子模式,當一個正則表達式成功與目標字符串匹配時,可以從目標串中抽出與圓括號中的子模式相匹配的部分。 還有
一個作用:在同一正則表達式后部引用前面的子表達式相匹配的文本的模式的引用,通過在字符"\"后加一位或多位數字來實現。這
個數字指定了正則表達式中括號的位置(參與計數的是左括號的位置)。
僅分組不提供引用: (?: )只提供分組功能,不能對其進行 \數字 進行引用。
指定匹配位置:只用于指定匹配的位置,不匹配某個可見的字符,指定匹配發生的合法位置。 如:^用來匹配字符串的開
始,多行檢索中,匹配一行的開頭,$用來匹配字符串的結束,多行檢索中,匹配一行的開頭。\b匹配一個單詞的邊界,即位于\w和
\W之間的邊界,或位于\w和字符串的開頭或者結尾之間的位置。\B匹配非單詞邊界的位置。
(?=p)要求接下來的字符都與p匹配,但不能包括p的那些字符。 (?!p)要求接下來的字符不與p匹配。
修飾符:它們不是位于\ \之間的,而是位于第二條\之后的,支持三個修飾符:
g:匹配是全局的,找出被檢索字符串中的所有匹配,而不是找到第一個之后就停止。
i:說明模式匹配是不區分大小寫的。
m:用于在多行模式中執行匹配,^ $除了匹配字符串的開始和結尾,還匹配每行的開始和結束。
執行正則表達式模式匹配和檢索替換操作的方法:
String中使用正則表達式的方法:
search():第一個參數是一個正則表達式,返回第一個與之匹配的字串的起始位置。如果找不到則返回-1。如果參
數不是正則表達式,通過RegExp()構造函數轉換為正則表達式。不支持全局索引。
replace():用于執行檢索與替換操作,第一個參數是一個正則表達式, 第二參數要進行替換的字符串,如果第一
個參數是字符串而不是正則表達式,則直接搜索這個字符串。第二個參數可以是一個函數,動態得計算替換字符串,也可以是$數
字,引用數字所代表括號的分組。
match():唯一參數是一個正則表達式,返回由匹配結果組成的數組。沒有設置修飾符g,就不會進行全局索引,只
索引第一個匹配,第一個元素是匹配到的完整的匹配,第二個元素是第一個括號括起來的表達式匹配的字串。
split():將調用它的 字符串或一個正則表達式參數 拆分成 一個字符串組成一個數組,使用的分隔符是split()的參數。
RegExp對象:
RegExp()構造函數:第一個參數是正則表達式的主體部分,就是/ /之間的部分,傳入字符串表述的正則表達式時,必須
將\替換成\\. 第二個參數是可選的,修飾符的組合。 在動態創建正則表達式時構造函數非常有用。
屬性:包含5個屬性:
1屬性source:只讀的字符串,包含正則表達式的文本。
2屬性global只讀的布爾值,說明這個正則表達式是否帶有修飾符g。
3屬性ignoreCase是一個只讀的布爾值,說明正則表達式是否帶有修飾符i。
4屬性multiline是一個只讀的布爾值,是否帶有修飾符m。
5屬性lastIndex是一個可讀寫的整數,如果匹配模式帶有g修飾符,這個屬性存儲在整個字符串中下一次檢索的開
始,每當在字符串找到最后一個匹配項后,在使用這個RegExp對象開始新的字符串查找之前,都應當將該屬性設置為0.
方法:
exec()方法:參數是一個字符串,和match()方法類似,沒有找到匹配返回null,找到匹配,結果與match()一樣,屬
性index包含發生匹配字符的位置,屬性input引用的是正在檢索的字符串。和match()方法不同,不管是否具有全局屬性g,返回的結
果的相同。 當具有g修飾符:把當前正則表達式對象的lastIndex屬性設置為緊挨著匹配的字符串的首字符位置(第二個匹配完整正則
表達式的字符串,非括號表示的子串),當第二次調用exec()時,將從將從lastIndex屬性所示的字符開始檢索,沒有匹配結果將
lastIndex設置為0。
test()方法:參數是一個字符串,如果包含正則表達式的一個匹配結果,則返回true。
8 注意點和具體問題詳解:
1.js中的作用域是通過作用域鏈來實現的, 這個鏈, 是由一個一個的活動對象組成的, 最頂級的活動對象是window
2. 在js中, 在每一個執行點, this關鍵字都指當前函數(方法)的所有者.
3. 每個屬性,其實都會定義成當前活動對象的屬性, 在頂級文件中的每個函數定義,變量定義, 都定義成window對象的屬性.
4. 對于函數, 如果通過函數表達式定義的函數, 則在函數表達式執行前, 該函數不可用. 而如果是通過函數定義式定義的函數, js會把它
的定義提前, 也就是說在函數定義式之前, 該函數都可用.
5. 因為活動對象鏈的特性, 所以js支持閉包.當一個函數嵌套另一個函數,
函數對象有可以訪問的prototype屬性, 一般對象不是沒有prototype屬性, 只是沒有可以訪問的prototype屬性.(嚴格來講, 一般對象只有
只能JS引擎內部訪問的”[[prototype]]”屬性
語句和表達式的區別:
JavaScript中的表達式和語句是有區別的.一個表達式會產生一個值,它可以放在任何需要一個值的地方,比如,作為一個函數調用的參數.
下面的每行代碼都是一個表達式:
myvar
3 + xmyfunc("a", "b")
語句可以理解成一個行為.循環語句和if語句就是典型的語句.一個程序是由一系列語句組成的.JavaScript中某些需要語句的地方,你可
以使用一個表達式來代替.這樣的語句稱之為
表達式語句.但反過來不可以:你不能在一個需要表達式的地方放一個語句.比如,一個if語句不能作為一個函數的參數.
var a=10; 與 a=10的區別:
當在過程級中聲明一個變量時,它不能用于全局范圍;這種情況下,變量聲明必須用var關鍵字。
⒈在一個過程級中(即位于function的定義范圍內,無論是函數,還是類)的任何地方,包括在一個區塊里(for,while,if……),定義變量時,使用var定義,則此變量只在這個
過程級內起作用,反之(不使用var定義,或在過程級外var定義的變量)為全局變量。
⒉在過程級外定義變量時,無論是否忽略var,都將定義一個全局變量。變量的邊界:
JS和其他語言有不一樣的地方,變量的范圍不以“{}”作為邊界,而是以"function(){}"為邊界,而且在過程內可以很輕松的定義全局變
量。如果不注意這個問題的話,是很容易產生不可預知的錯誤的。
對于使用var,我的建議是要養成好的使用習慣:
⒈在程序的開頭,統一定義全局變量;
⒉所有的變量在定義時都要加上var;
⒊盡量不要在不同的過程中使用相同的變量名。