體驗javascript之“變態

 

學習Javascript斷斷續續也有十幾天瞭,總結一下為自己也為別人。Javascript給我的整體印象就是很“隨便”,這種印象緣起於它的面向對象。當然Javascript的靈活性也註定瞭它是一個隨便的語言。

Javascript的語法特性

Javascript是一門動態的,弱類型的,基於原型的腳本語言。我們在一些網站上的一些漂浮效果(雖然很討厭),圖片切換效果,還有一些文本編輯器等等,這都要歸功於Javascript。當然Javascript又是一個徹底的面向對象的語言,雖然你看到的是遍地的function(),但是誰有規定函數不能是對象呢。下面來看一些具體的內容。

Javascript基本語法

但凡有一點編程基礎的人都會覺得Javascript的語法很簡單,非常容易上手,但這並不代表Javascript很容易學習,精通Javascript也不是一件易事。

Javascript有五種基本的數據類型:數值(Number),字符串(String),佈爾類型(boolean),Null類型,Undefined類型。

上面已經說過瞭Javascript是一種動態的弱類型語言,那我們就來看看Javascript動態體現在哪裡,弱類型又體現在哪裡:

 

//聲明變量 

var attr1 = 1; 

var attr2 = 1.03; 

var attr3 = "hello"; 

var attr4 = false; 

 

不用像java中那樣,想聲明什麼類型的變量還必須提前定義,在Javascript中,我們"信手拈來"就可以瞭,它是什麼樣它就是什麼類型。口說無憑,有代碼有真相。我們可以通過Javascript的typeof關鍵字來測試,一試便知。

 

//聲明變量 

var attr0 ; 

var attr1 = 1; 

var attr2 = 1.03; 

var attr3 = "hello"; 

var attr4 = false; 

             

alert(typeof attr0); //undefined 

alert(typeof attr1); //number 

alert(typeof attr2); //number   

alert(typeof attr3); //string 

alert(typeof attr4); //boolean 

alert(typeof null); //object 

alert(typeof undefined); //undefined 

 

這裡也還有一個知識點是關於null和undefined的。Null是一個空的對象,的的類型為Object;undefined是全局對象(Window)的一個屬性,所以他的類型還是undefined。但是undefined是從null繼承來的。Javascript的基本語法非常的簡單,大致瀏覽就可以上手,所以其他的東西就不在這裡說瞭。開始下一小節…

Javascript作用域

Javascript的作用域是非常個性的,我們先來看幾個例子體驗一下。

 

// 作用域 

var outer = 1; 

function layer() { 

    var layer1 = 2; 

    function inner() { 

        var layer2 = 3; 

        alert(layer1);//2 

        alert(layer2);//3 

    } 

    inner(); 

layer(); 

             

alert(outer);//1 

alert(layer1);//layer1已經被回收 

alert(layer2);//layer2已經被回收 

這個是和其他編程語言相似的地方,主要涉及全局變量和局部變量;全局變量和局部變量的作用范圍既不用細說瞭吧。

 

 

// sample2  

var x = "smile"; 

var alerts = function() { 

    alert(x); //undefined 

    var x = "fuck";  

    alert(x); //fuck 

         

    //上面的相當於下面的代碼 

    //var x ; 

    //alert(x); //undefined 

    //x = "fuck"; 

    //alert(x); //fuck 

Javascript沒有塊級作用域,函數中聲明的所有變量無論是在哪裡聲明的,在整個函數中都有意義。估計對於用熟java語言的程序猿這一點是不容易接受的,反正我是這樣。還有一個比較靈活的地方:未使用var聲明的變量都是全局變量,而且全局變量都是Window對性的屬性。呵呵…又糾結瞭,適應就好瞭!!

Javascript 的閉包

在實現深約束時,需要創建一個能顯式表示引用環境的東西,並將它與相關的子程序捆綁在一起,這樣捆綁起來的整體被稱為閉包。單從這樣一個定義上說我們並不容易理解什麼是閉包。拿一個例子說事…

 

 //閉包演示 

var func = function() { 

    var attr = "can read me??"; 

    return function() { 

        alert(attr); 

    } 

func()(); 

 

本來我們已經無法在func函數的外面訪問到attr屬性,但是"can read me??"確確實實通過alert()方法彈出來瞭,這是為什麼呢,難道最後那個當做返回值的匿名函數幫我們保存瞭attr屬性?當然調用此函數的方式也有一些奇怪:func()()。我們做進一步詳細的介紹。

當調用一個Javascript 函數時,該函數就會進入相應的執行環境。如果又調用瞭另外一個函數(或者遞歸地調用同一個函數),則又會創建一個新的執行環境,並且在函數調用期間執行過程都處於該環境中。當調用的函數返回後,執行過程會返回原始執行環境。同時創建的執行環境會包含一個作用域鏈,這個作用域鏈是通過將該執行環境的活動(可變)對象添加到保存於所調用函數對象的[[scope]] 屬性中的作用域鏈前端而構成的。

結合上面的例子簡單分析一下,func()函數返回瞭一個匿名的函數function,所以被返回的匿名函數他的執行環境和作用域鏈不會被回收,當我們訪問attr屬性的時候,我很會直接到function運行環境的作用域鏈中去查找。(對於這塊內容涉及的Javascript內容比深奧,也不怎麼理解,不過可以參考:https://www.cn-cuckoo.com/2007/08/01/understand-Javascript-closures-72.html )。

Javascript面向對象

Javascript的面向對象真是有點詭異,因為Javascript是一個函數式編程語言,雖然我們可以模擬繼承,封裝等面向對象的特性,但是總是不如java這樣的語言感覺更自然,當然不排除自己的主觀因素。我們先來模擬一下Javascript的面向對象,體驗一下。

方式一:最原始的方式

 

var car = new Object(); 

car.color = "red"; 

car.speed = 100; 

car.showColor = function() { 

    alert(this.color); 

}; 

 

car.showColor(); 

 

方式二:運用工廠

 

function createCar() { 

    var car = new Object(); 

    car.color = "red"; 

    car.speed = 100; 

    car.showColor = function() { 

        alert(this.color); 

    }; 

    return car; 

var car = createCar(); 

car.showColor(); 

 

方式三:運用構造函數

 

function Car(color, speed) { 

    this.color = color; 

    this.speed = speed; 

    this.showColor = function() { 

        alert(this.color); 

    }; 

var car = new Car("blue", 400); 

car.showColor(); 

 

方式四:運用原型方式

 

function Car() { 

Car.prototype.color = "blue"; 

Car.prototype.speed = 300; 

Car.prototype.showColor = function() { 

    alert(this.color); 

}; 

var car = new Car(); 

car.showColor(); 

 

方式五:混合構造函數和原型方式

 

function Car(color, speed) { 

    this.color = color; 

    this.speed = speed; 

    this.drivers = new Array("mike", "sue"); 

Car.prototype.showColor = function() { 

    alert(this.color); 

}; 

var car1 = new Car("green", 300); 

car1.drivers.push("wangkang"); 

car1.showColor(); 

alert(car1.drivers.join()); 

 

var car2 = new Car("black", 300); 

car2.showColor(); 

alert(car2.drivers.join()); 

 

方式六:動態原型方法

 

function Car(color, speed) { 

    this.color = color; 

    this.speed = speed; 

    this.drivers = new Array("mike", "sue"); 

if (typeof Car._initialized == "undefined") { 

    Car.prototype.showColor = function() { 

        alert(this.color); 

    }; 

    Car._initialized = true; 

var car1 = new Car("green", 300); 

car1.drivers.push("wangkang"); 

car1.showColor(); 

alert(car1.drivers.join()); 

 

var car2 = new Car("black", 300); 

car2.showColor(); 

alert(car2.drivers.join()); 

 

方式七:混合工廠

 

function Car() { 

    var car = new Object(); 

    car.color = "red"; 

    car.speed = 100; 

    car.showColor = function() { 

        alert(this.color); 

    }; 

    return car; 

var car = new Car(); 

car.showColor(); 

 

畢竟面向對象隻是一種編程的思想,用的多瞭其義自現,因為自己沒有學習多長時間的Javascript,所以內部的機制不是很理解,但是通過上面推薦的那篇文章肯定有幫助,因為它是從Javascript運行機制上進行瞭徹底的分析。

隻是給大傢進行一個Javascript的掃盲,所以力求文章中沒有錯誤,思想少瞭一點,例子多瞭一點!還有那一片推薦的博客希望大傢認真的琢磨幾遍,如果理解瞭那篇博客那麼Javascript的作用域,閉包,面向對象等特性就非常容易理解瞭。https://www.cn-cuckoo.com/2007/08/01/understand-Javascript-closures-72.html

發佈留言