前端學習實踐筆記--JavaScript深入【1】


       這一年中零零散散看過幾本javascript的書,回過頭看之前寫過的javascript學習筆記,未免有點汗顏,突出“膚淺”二字,然越深入越覺得javascript的博大精深,有種只緣身在此山中的感覺,茫茫然而不得其要領,索性在一邊寫博文中,求得突破,乃至更上一層樓。

       看過的書籍推薦:

       《javascript語言精粹》 Douglas Crockford

       《javascript設計模式》 Addy Osmani

       《javascript設計模式》 Ross Harmes

       《悟透javascript》   李戰

       《javascript語言精髓與編程實踐》 周愛民

        這些書是在絕大部分javascript書籍中較好的幾本了,市面上的javascript,不得不說,水分太多,養分太少。很多書翻幾頁也就困了。反倒是網上有些不錯的博客,博客園里面,博客園的知識庫里面,還有一些其他的個人博客,都是挺不錯的,但是大多都比較分散,知識點也比較散落。另外由於隨着javascript本身的更新,還有jQuery,YUI等一系列插件的出現,NodeJS興起等等的影響,不同瀏覽器的更新以及兼容性問題,導致了原生JS的逐漸冷落,但是不管怎么說,也遮不住JS這門語言本身的魅力。

        JS有很多深邃的地方值得學習,接下來着重介紹一些比較好玩的東西,這些也是我看了很多的書和博文累積起來的,但是最好的讀者是稍微有點JS基礎了,因為我講的東西可能會有點跳躍,不是基礎的教程。

       不講解那些復雜拗口的語法,或者那些深坑,或者那些晦澀難懂的設計模式,通過簡單的實例來學習實踐區分靜態語言和動態語言的區別於共同點

       樓主是一個記性很差,特別怕麻煩的人,樓主忠於且堅信用最簡單的技術實現用戶需求,能抓老鼠的貓才是貓的原則,反對過分追求優化,追求復雜的設計模式。

       只求能干凈的實現我的功能。主要分以下幾點來講解:
       1. var 變量 聲明 函數聲明 提前

       2. call apply的使用

       3. new 實例化,復制,引用的區別

       4. 原型鏈的使用

       5. 閉包保持用戶狀態

       6. 面向對象的實現,繼承

       7. this指針

       8. 數組,對象,json

       9. AMD,CMD簡介 

       10. js中的深坑

       11. 繼續深入方向

 

1. var 變量 聲明 函數聲明提前

     提到變量/函數聲明,理解一個核心,JS的解析和執行時分開的,了解了這個,很多問題和怪事就都明白了。

     JS代碼在執行的時候,會經過兩個步驟,首先是解析(預編譯),然后再執行。解析就是聲明變量,還沒有賦值,所以是undefined的,到了具體執行的時候才會給予具體的值。要把一條賦值語句分成兩部分看,例如var a = 5; 應該是 var a; a = 5;這樣兩部分看,復雜的情況如下幾個例子:     

         

/**
 * 變量聲明和函數表達式(我更覺得應該叫定義,但是大家好像默認都是聲明了)
 * 都是用var來聲明,所以如果將函數具體內容看做是一個值得話,跟變量賦值其實是一回事
 * 下面語句執行的順序如下:
 * 首先進行變量聲明,即var f;所以第一個輸出時undefined
 * 因為有兩個var f的定義,之后的定義覆蓋之前的定義,所以第二個輸出時25
 * 第三個輸出時f函數的具體內容
 * 如果將var f = 0; 和var f = function(x){return x*x;}順序倒過來,那第二個輸出就要報錯了,
 * 第三個輸出是0
 *
 */
//console.log(f);
//var f = 0;
//var f = function(x){
//    return x*x;
//}
//console.log(f(5));
//console.log(f);

/**
 * 變量聲明和函數聲明
 * 下面語句的執行輸出結果如下:
 * 第一個輸出是函數的具體內容
 * 第二個輸出是16,
 * 第三個輸出是0
 * 問題在於從技術上說,function語句並非是一個語句.
 * JS中語句會引發動態的行為,
 * 但是函數定義描述的卻是靜態的程序結構。
 * 語句是在運行時執行的,而函數則是實際運行之前,
 * 當JS代碼被解析或被編譯時定義的。
 * 當JS解析程序遇到一個函數定義時,它就解析並存儲構成函數主體的語句,
 * 然后定義一個和該函數同名的屬性
 * (如果函數定義在其它的函數中,那么就在調用對象中定義這個屬性,
 * 否則在全局對象中定義這個屬性)以保存它。這會產生一些奇怪的行為。
 * 總結來說就是函數聲明優於比變量聲明。
 */
console.log(f);
console.log(f(4));
function f(x){
    return x*x;
}
var f = 0;
console.log(f);

 

      事實上,js的解析器對函數聲明與函數表達式並不是一視同仁地對待的。對於函數聲明,js解析器會優先讀取,確保在所有代碼執行之前聲明已經被解析,而函數表達式,如同定義其它基本類型的變量一樣,只在執行到某一句時也會對其進行解析,所以在實際中,它們還是會有差異的,具體表現在,當使用函數聲明的形式來定義函數時,可將調用語句寫在函數聲明之前,而后者,這樣做的話會報錯。

2. call  apply的使用

     1、方法定義

     call方法: 
     語法:call([thisObj[,arg1[, arg2[,   [,.argN]]]]]) 
     定義:調用一個對象的一個方法,以另一個對象替換當前對象。 
     說明: 
     call 方法可以用來代替另一個對象調用一個方法。call 方法可將一個函數的對象上下文從初始的上下文改變為由 thisObj 指定的新對象。 
     如果沒有提供 thisObj 參數,那么 Global 對象被用作 thisObj。 

      apply方法: 
     語法:apply([thisObj[,argArray]]) 
     定義:應用某一對象的一個方法,用另一個對象替換當前對象。 
     說明: 
     如果 argArray 不是一個有效的數組或者不是 arguments 對象,那么將導致一個 TypeError。 
     如果沒有提供 argArray 和 thisObj 任何一個參數,那么 Global 對象將被用作 thisObj, 並且無法被傳遞任何參數。

     簡單來說,區別就是apply方法后面傳遞的參數是數組,而call方法是add.call(doubleAdd,a,b,c)形式的.  具體執行的方法看call、apply前面的函數,

如果沒有提供thisObj,相當於Global。

     具體來說,看幾個例子:

function add(a,b)
{
    alert(a+b);
}
function sub(a,b)
{
    alert(a-b);
}

add.call(sub,3,1);  //== add.call(null,3,1);
//輸出4

sub.call(null,3,1);
//輸出2

   

//這里稍微涉及到this指針,this指向的是運行時的上下文
function Class1()
{
    this.name = "class1";

    this.showNam = function()
    {
        alert(this.name);
    }
    this.detail = "hello-1";
    this.showDetail = function(){
        alert(this.detail);
    }
}

function Class2()
{
    this.name = "class2";
    this.detail = "hello-2";
    this.showDetail = function(){
        alert(this.detail);
    }
}

var c1 = new Class1();
var c2 = new Class2();

c1.showNam.call(c2);
c1.showNam();
c1.showDetail();
c2.showDetail();
// class2
// class1
//hello-1
//hello-2

     還可以用call實現繼承,具體例子就不給出了,參考文章JS中的call()和apply()方法 ...里面寫的很詳細,該說的也都說了。

 3. new 實例化,復制,引用的區別

     記住function有對象化能力,體現在使用new上。如果沒有使用new新創建一個對象(即復制一份相同內容), 即還是引用,對函數內部變量的改變會導致其他引用值的改變。

     這里涉及到對象的概念,統一在對象的時候再說吧。。今天就寫到這里了。

 

 

以上全部都屬個人原創,請大家轉載的時候附上原創鏈接: http://www.cnblogs.com/tonylp


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM