《javascript語言精粹》讀書筆記(二)

第三章 對象
javascript

    javascript的簡單類型包括數字、字符串、布爾值、null值和undefined值,其餘全部的值都是對象。
java

    javascript包含一個原型鏈特性,容許對象繼承另外一對象的屬性。正確的使用它能減小對象初始化的時間和內存消耗。node

    3.1對象字面量編程

如:var person={
        "name":"John",
        "age":18,
        "wife":{
            "name":"Lucy",
            "agen":22
        }
    }

    3.2檢索設計模式

        點表示法或[]表示法。如:數組

person.name;
person["name"];

    3.3更新
閉包

        對象中的值能夠賦值更新,若是已有屬性,那麼屬性值被替換;若沒有屬性,則該屬性會被擴充到對象中。
app

    3.4引用
編程語言

        對象經過引用傳遞,他們永遠不會被拷貝。(傳遞的僅僅是地址)
函數

    3.5原型

        (1)每一個對象都鏈接到一個原型對象--Object.prototype這個標準對象。

        (2)原型鏈接在更新時是不起做用的,當咱們改變某個對象的屬性值時,不會觸及到對象的原型。(只針對於實例屬性的修改,對於原型上的引用類型會改變對象的原型)

        (3)原型鏈只有在檢索值的時候用到,當嘗試獲取某個對象的屬性值時,會沿着他的原型鏈從下到上依次找,直到Object.prototype,若是Object.prototype依然沒有該屬性,則返回undefined。這個過程稱爲委託。

        (4)原型關係是一種動態的關係,若是添加一個新的屬性到原型中,該屬性會當即對全部基於該原型建立的對象可見。

    3.6反射

        (1)typeof操做符用於肯定屬性的類型。

        (2)hasOwnProperty對象是否擁有獨立的屬性,他不會檢測原型鏈上的。

person.hasOwnProperty("name");//true
person.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();    //以方法形式調用double
myObject.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記憶

        提供了一個設計思路以提升執行效率,減小循環次數。

相關文章
相關標籤/搜索