學(xué)習(xí)Javascript斷斷續(xù)續(xù)也有十幾天了,總結(jié)一下為自己也為別人。Javascript給我的整體印象就是很“隨便”,這種印象緣起于它的面向?qū)ο?。?dāng)然Javascript的靈活性也注定了它是一個(gè)隨便的語(yǔ)言。
Javascript的語(yǔ)法特性
Javascript是一門動(dòng)態(tài)的,弱類型的,基于原型的腳本語(yǔ)言。我們?cè)谝恍┚W(wǎng)站上的一些漂浮效果(雖然很討厭),圖片切換效果,還有一些文本編輯器等等,這都要?dú)w功于Javascript。當(dāng)然Javascript又是一個(gè)徹底的面向?qū)ο蟮恼Z(yǔ)言,雖然你看到的是遍地的function(),但是誰(shuí)有規(guī)定函數(shù)不能是對(duì)象呢。下面來(lái)看一些具體的內(nèi)容。
Javascript基本語(yǔ)法
但凡有一點(diǎn)編程基礎(chǔ)的人都會(huì)覺(jué)得Javascript的語(yǔ)法很簡(jiǎn)單,非常容易上手,但這并不代表Javascript很容易學(xué)習(xí),精通Javascript也不是一件易事。Javascript有五種基本的數(shù)據(jù)類型:數(shù)值(Number),字符串(String),布爾類型(boolean),Null類型,Undefined類型。
上面已經(jīng)說(shuō)過(guò)了Javascript是一種動(dòng)態(tài)的弱類型語(yǔ)言,那我們就來(lái)看看Javascript動(dòng)態(tài)體現(xiàn)在哪里,弱類型又體現(xiàn)在哪里:
//聲明變量
var attr1 = 1;
var attr2 = 1.03;
var attr3 = "hello";
var attr4 = false;
不用像java中那樣,想聲明什么類型的變量還必須提前定義,在Javascript中,我們"信手拈來(lái)"就可以了,它是什么樣它就是什么類型。口說(shuō)無(wú)憑,有代碼有真相。我們可以通過(guò)Javascript的typeof關(guān)鍵字來(lái)測(cè)試,一試便知。
//聲明變量
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
這里也還有一個(gè)知識(shí)點(diǎn)是關(guān)于null和undefined的。Null是一個(gè)空的對(duì)象,的的類型為Object;undefined是全局對(duì)象(Window)的一個(gè)屬性,所以他的類型還是undefined。但是undefined是從null繼承來(lái)的。Javascript的基本語(yǔ)法非常的簡(jiǎn)單,大致瀏覽就可以上手,所以其他的東西就不在這里說(shuō)了。開(kāi)始下一小節(jié)...
Javascript作用域
Javascript的作用域是非常個(gè)性的,我們先來(lái)看幾個(gè)例子體驗(yàn)一下。
// 作用域
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已經(jīng)被回收
alert(layer2);//layer2已經(jīng)被回收
這個(gè)是和其他編程語(yǔ)言相似的地方,主要涉及全局變量和局部變量;全局變量和局部變量的作用范圍既不用細(xì)說(shuō)了吧。
// sample2
var x = "smile";
var alerts = function() {
alert(x); //undefined
var x = "fuck";
alert(x); //fuck
//上面的相當(dāng)于下面的代碼
//var x ;
//alert(x); //undefined
//x = "fuck";
//alert(x); //fuck
}
Javascript沒(méi)有塊級(jí)作用域,函數(shù)中聲明的所有變量無(wú)論是在哪里聲明的,在整個(gè)函數(shù)中都有意義。估計(jì)對(duì)于用熟java語(yǔ)言的程序猿這一點(diǎn)是不容易接受的,反正我是這樣。還有一個(gè)比較靈活的地方:未使用var聲明的變量都是全局變量,而且全局變量都是Window對(duì)性的屬性。呵呵...又糾結(jié)了,適應(yīng)就好了?。?/span>
Javascript 的閉包
在實(shí)現(xiàn)深約束時(shí),需要?jiǎng)?chuàng)建一個(gè)能顯式表示引用環(huán)境的東西,并將它與相關(guān)的子程序捆綁在一起,這樣捆綁起來(lái)的整體被稱為閉包。單從這樣一個(gè)定義上說(shuō)我們并不容易理解什么是閉包。拿一個(gè)例子說(shuō)事...
//閉包演示
var func = function() {
var attr = "can read me??";
return function() {
alert(attr);
}
}
func()();
本來(lái)我們已經(jīng)無(wú)法在func函數(shù)的外面訪問(wèn)到attr屬性,但是"can read me??"確確實(shí)實(shí)通過(guò)alert()方法彈出來(lái)了,這是為什么呢,難道最后那個(gè)當(dāng)做返回值的匿名函數(shù)幫我們保存了attr屬性?當(dāng)然調(diào)用此函數(shù)的方式也有一些奇怪:func()()。我們做進(jìn)一步詳細(xì)的介紹。
當(dāng)調(diào)用一個(gè) Javascript 函數(shù)時(shí),該函數(shù)就會(huì)進(jìn)入相應(yīng)的執(zhí)行環(huán)境。如果又調(diào)用了另外一個(gè)函數(shù)(或者遞歸地調(diào)用同一個(gè)函數(shù)),則又會(huì)創(chuàng)建一個(gè)新的執(zhí)行環(huán)境,并且在函數(shù)調(diào)用期間執(zhí)行過(guò)程都處于該環(huán)境中。當(dāng)調(diào)用的函數(shù)返回后,執(zhí)行過(guò)程會(huì)返回原始執(zhí)行環(huán)境。同時(shí)創(chuàng)建的執(zhí)行環(huán)境會(huì)包含一個(gè)作用域鏈,這個(gè)作用域鏈?zhǔn)峭ㄟ^(guò)將該執(zhí)行環(huán)境的活動(dòng)(可變)對(duì)象添加到保存于所調(diào)用函數(shù)對(duì)象的 [[scope]] 屬性中的作用域鏈前端而構(gòu)成的。
結(jié)合上面的例子簡(jiǎn)單分析一下,func()函數(shù)返回了一個(gè)匿名的函數(shù)function,所以被返回的匿名函數(shù)他的執(zhí)行環(huán)境和作用域鏈不會(huì)被回收,當(dāng)我們?cè)L問(wèn)attr屬性的時(shí)候,我很會(huì)直接到function運(yùn)行環(huán)境的作用域鏈中去查找。(對(duì)于這塊內(nèi)容涉及的Javascript內(nèi)容比深?yuàn)W,也不怎么理解,不過(guò)可以參考:http://www.cn-cuckoo.com/2007/08/01/understand-Javascript-closures-72.html )。
Javascript面向?qū)ο?/span>
Javascript的面向?qū)ο笳媸怯悬c(diǎn)詭異,因?yàn)?/span>Javascript是一個(gè)函數(shù)式編程語(yǔ)言,雖然我們可以模擬繼承,封裝等面向?qū)ο蟮奶匦?,但是總是不?/span>java這樣的語(yǔ)言感覺(jué)更自然,當(dāng)然不排除自己的主觀因素。我們先來(lái)模擬一下Javascript的面向?qū)ο?,體驗(yàn)一下。
方式一:最原始的方式
var car = new Object();
car.color = "red";
car.speed = 100;
car.showColor = function() {
alert(this.color);
};
car.showColor();
方式二:運(yùn)用工廠
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();
方式三:運(yùn)用構(gòu)造函數(shù)
function Car(color, speed) {
this.color = color;
this.speed = speed;
this.showColor = function() {
alert(this.color);
};
}
var car = new Car("blue", 400);
car.showColor();
方式四:運(yùn)用原型方式
function Car() {
}
Car.prototype.color = "blue";
Car.prototype.speed = 300;
Car.prototype.showColor = function() {
alert(this.color);
};
var car = new Car();
car.showColor();
方式五:混合構(gòu)造函數(shù)和原型方式
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());
方式六:動(dòng)態(tài)原型方法
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();
畢竟面向?qū)ο笾皇且环N編程的思想,用的多了其義自現(xiàn),因?yàn)樽约簺](méi)有學(xué)習(xí)多長(zhǎng)時(shí)間的Javascript,所以內(nèi)部的機(jī)制不是很理解,但是通過(guò)上面推薦的那篇文章肯定有幫助,因?yàn)樗菑?/span>Javascript運(yùn)行機(jī)制上進(jìn)行了徹底的分析。
只是給大家進(jìn)行一個(gè)Javascript的掃盲,所以力求文章中沒(méi)有錯(cuò)誤,思想少了一點(diǎn),例子多了一點(diǎn)!還有那一片推薦的博客希望大家認(rèn)真的琢磨幾遍,如果理解了那篇博客那么Javascript的作用域,閉包,面向?qū)ο蟮忍匦跃头浅H菀桌斫饬恕?/span>http://www.cn-cuckoo.com/2007/08/01/understand-Javascript-closures-72.html