學習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中,我們"信手拈來"就可以了,它是什么樣它就是什么類型??谡f無憑,有代碼有真相。我們可以通過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對性的屬性。呵呵...又糾結了,適應就好了?。?/span>
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內容比深奧,也不怎么理解,不過可以參考:http://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的作用域,閉包,面向對象等特性就非常容易理解了。http://www.cn-cuckoo.com/2007/08/01/understand-Javascript-closures-72.html