標籤:
第三章 對象
javascript的簡單類型包括數字、字串、布爾值、null值和undefined值,其他所有的值都是對象。
javascript包含一個原型鏈特性,允許對象繼承另一對象的屬性。正確的使用它能減少對象初始化的時間和記憶體消耗。
3.1對象字面量
如:var person={ "name":"John", "age":18, "wife":{ "name":"Lucy", "agen":22 } }
3.2檢索
點標記法或[]標記法。如:
person.name;person["name"];
3.3更新
對象中的值可以賦值更新,如果已有屬性,那麼屬性值被替換;若沒有屬性,則該屬性會被擴充到對象中。
3.4引用
對象通過引用傳遞,他們永遠不會被拷貝。(傳遞的僅僅是地址)
3.5原型
(1)每個對象都串連到一個原型對象--Object.prototype這個標準對象。
(2)原型串連在更新時是不起作用的,當我們改變某個對象的屬性值時,不會觸及到對象的原型。
(3)原型鏈只有在檢索值的時候用到,當嘗試擷取某個對象的屬性值時,會沿著他的原型鏈從下到上依次找,直到Object.prototype,如果Object.prototype依然沒有該屬性,則返回undefined。這個過程稱為委託。
(4)原型關係是一種動態關係,如果添加一個新的屬性到原型中,該屬性會立即對所有基於該原型建立的對象可見。
3.6反射
(1)typeof操作符用於確定屬性的類型。
(2)hasOwnProperty對象是否擁有獨立的屬性,他不會檢測原型鏈上的。
person.hasOwnProperty("name");//trueperson.hasOwnProperty("c");//false
3.7枚舉
for in語句會遍曆對象的所有屬性,包括原型鏈上的屬性。可以用typeof和hasOwnPropery過濾。
3.8刪除
delete操作符會刪除對象的屬性,但不會觸及原型鏈上的屬性。
3.9減少全域變數汙染
最小化使用全域變數的一個方法是你的應用中只建立唯一一個全域變數。
var MYAPP={};MYAPP.stooge={ "first-name":"Joe", "last-name":"Howard"}MYAPP.person={ "name":"John", "age":18, "wife":{ "name":"Lucy", "agen":22 } }
第四章 函數
4.1函數對象
在javascript中函數就是對象,他串連到Function.prototype(該原型對象本身串連到Object.prototype)。
每個函數對象在建立時也會帶有一個prototype屬性,他的值中擁有一個constructor屬性,constructor屬性的值即為該函數的對象。
4.2函數字面量
var add = function(a,b){ return a+b;}
通過函數字面量建立的函數對象包含一個連到外部內容的串連,這被稱為閉包。他是javascript強大表現力的根基。
4.3調用
除了聲明時定義的形式參數,每個函數接受兩個附加參數:this和arguments(實際參數)。this的值取決於函數調用的模式。javascript一共有四種調用模式:方法調用模式、函數調用模式、構造器調用模式和apply調用模式。
(1)方法調用模式
當一個函數被儲存為一個對象的屬性時,我們稱它為一個方法。
var myObjec={ value:0, increment:function(inc){ this.value += typeof inc === ‘number‘ ? inc : 1; }}myObject.increment();console.log(myObject.value);//1
通過this可取得它所屬對象的內容相關的方法稱為公用方法。
(2)函數調用模式
當一個函數並非一個對象的屬性時,那麼它被當做一個函數來調用。
var sum=add(3,4); //7
當函數以此模式調用時,this被綁定到全域對象。書中說這個設計是錯誤的,因為外部函數無法利用內建函式來協助他工作,因為內建函式的this綁定了錯誤的值,不能共用該方法對對象的訪問權(即不能在內建函式中用this訪問對象的屬性,因為this指向了全域變數)。書中提供了一個解決方案:
//給myObject添加一個double方法myObject.double=function(){ var that=this; //解決方案 var helper=function(){ that.value=add(that.value,that.value); } helper(); //以函數形式調用helper();}myObject.double(); //以方法形式調用doublemyObject.getValue(); //6
(3)構造器調用模式
就是建立一個函數,然後用new操作符去調用它,這樣就建立了這個函數(類)的一個執行個體,同時this會綁定到這個新執行個體(對象)上。
(例子比較簡單,就直接了)
(4)Apply調用模式
由於javascript是一門函數式的物件導向程式設計語言,所以函數可以擁有方法。
其實就是將方法的執行範圍更改了,放到了apply的一個參數中,和call的作用是一樣的。
4.4參數
函數被調用時,內部自動獲得一個arguments數組,通過他可以訪問所有函數被調用時的參數列表。
arguments並不是一個真正的數組,它只是一個類數組的對象,它擁有length屬性,卻沒有數組的方法。
4.5返回
每個函數都有傳回值(return),若沒有指定,則返回undefined。
以new調用的函數,且傳回值不是對象,則返回this(該新對象)。
4.6異常
javascript也提供了異常處理機制。
var add=function(a,b){ if(typeof a!==‘number‘){ throw{ ‘name‘:‘TypeError‘, ‘message‘:‘add needs numbers‘ }; } return a+b;}
throw語句中斷函數的執行,拋出一個exception對象,該對象包括一個可識別的異常類型name和一個描述性message。你也可以添加其他屬性。
該exception對象將傳遞到一個try語句的catch從句。
var try_it=function(){ try{ add("seven"); }catch(e){ console.log(e.name+":"+e.message); }}try_it();
4.7給類型增加方法
通過給Function.prototype添加方法使得該方法對所有函數可用:
Function.prototype.method=function(name,func){ if(!this.prototype[name]){ this.prototype[name]=func; } return this;}
為Number的原型添加一個integer方法取整:
Number.method(‘integer‘,function(){ return Math[this<0?‘ceiling‘:‘floor‘](this);});console.log((-3/10).integer()); //-3
為String添加一個去除兩側空格的方法:
String.method(‘trim‘,function(){ return this.replace(/^\s+|\s+$/g,‘‘);});
這樣就省去了prototype。個人覺得書中的這種寫法很牛逼!
4.8遞迴(略)
4.9範圍
javascript沒有塊級範圍,只有函數級範圍,所以盡量把變數定義在函數的頂部。
4.10閉包
函數可以訪問他被建立時所處的上下文環境,稱為閉包。就是說,內建函式一直保留著對外部函數屬性的引用,這個屬性會一直存在記憶體中。
//糟糕的例子var addHandlers=function(nodes){ var i; for(i;i<nodes.lengh;i++){ nodes[i].onclick=function(e){ alert(i); } }}
書中沒說導致的結果是什麼,我覺得應該是,點擊任意節點alert的結果都是一樣的,即最後一個node值,因為onclick函數一直保持著對i的引用。
//更好的例子var addHandlers=function(nodes){ var i; for(i;i<nodes.lengh;i++){ nodes[i].onclick=function(e){ //書中此處的形參寫的是i,應該是寫錯了 return function(e){ alert(e); } }(i) }}
4.11回調callback(略)
4.12模組
此處實際上是介紹了一個設計模式--模組模式,它通常和單體模式一起使用,目的是利用函數和閉包減少全域變數帶來的弊端。
var serial_maker=function(){ //實際上此處是定義了2個局部變數,一直放在記憶體中,但外部是不可訪問的 var prefix=‘‘; var seq=0; return{ set_prefix:function(p){ prefix=String(p); }, set_seq:function(s){ seq=s; }, gensym:function(){ var result=prefix+seq; seq+=1; return result; } }; };var seqer=serial_maker();seqer.set_prefix(‘Q‘);sequer.set_seq(1000);var unique=seqer.gensym(); //Q1000
4.13級聯(略)--相當於jQuery的鏈式操作,都返回this
4.14套用(略)--感覺用處不大
4.15記憶
提供了一個設計思路以提高執行效率,減少迴圈次數。
《javascript語言精粹》讀書筆記(二)