寫此文目的是為了讓更多的程序員理解javascript的一些概念,對(duì)是理解不是了解
我們已經(jīng)了解得夠多了,該是向深入理解的方向靠攏的時(shí)候了
為什么這么說,前些日子收到面試邀請(qǐng),那就去試試唄,有幾年沒有面試過了吧
和面試官坐在沙發(fā)上,聊天式的他問我答,以下就是幾個(gè)javascript方面的問題
>請(qǐng)創(chuàng)建一個(gè)對(duì)象,包括幾個(gè)公有屬性,接下來是為對(duì)象創(chuàng)建一個(gè)公有方法,然后為對(duì)象創(chuàng)建幾個(gè)私有屬性,一個(gè)私有方法
說實(shí)話,這幾個(gè)問題我默名其妙,要是他讓我用jquery寫個(gè)拖動(dòng)插件什么的,我估計(jì)我能寫挺好,原生的javascript,暈,雖然我看過jquery源碼解讀,但這些基本概念要命
稍后,我會(huì)在正文中將答案寫出來
如果面試官在看,說聲謝謝,面試完之后我就去深圳購書中心買javascript去了,好貴,呵呵,看中之后,到卓越定了一個(gè)《javascript王者歸來》
然后基本上啥也沒干,仔細(xì)的看了一個(gè)多星期,看不明白的就到園子里來找,園子里的寶貝真不少?。ㄟ€壓了個(gè)韻。。。)
本文的例子輸出使用如下方法,便于查看
function dwn(s){
document.write(s+"<br/>");
}
以下內(nèi)容有些是原創(chuàng),有些來自于網(wǎng)絡(luò),或者可以看成是讀書筆記,如果有哪里不對(duì)的,請(qǐng)各位不吝賜教,在下感激不盡
正文開始:
一,function
從一開始接觸到j(luò)s就感覺好靈活,每個(gè)人的寫法都不一樣,比如一個(gè)function就有N種寫法
如:function showMsg(){},var showMsg=function(){},showMsg=function(){}
似乎沒有什么區(qū)別,都是一樣的嘛,真的是一樣的嗎,大家看看下面的例子
///------------------------------------------------------------------------------------------------
//函數(shù)定義:命名函數(shù)(聲明式),匿名函數(shù)(引用式)
//聲明式,定義代碼先于函數(shù)執(zhí)行代碼被解析
function t1(){
dwn("t1");
}
t1();
function t1(){
dwn("new t1");
}
t1();
//引用式,在函數(shù)運(yùn)行中進(jìn)行動(dòng)態(tài)解析
var t1=function(){
dwn("new new t1");
}
t1();
var t1=function(){
dwn("new new new t1");
}
t1();
//以上輸出:new t1,new t1,new new t1,new new new t1
可能想著應(yīng)該是輸出t1,new t1,new newt1,new new new t1,結(jié)果卻并不是這樣,應(yīng)該理解這句話:聲明式,定義代碼先于函數(shù)執(zhí)行代碼被解析
如果深入一步,應(yīng)該說是scope鏈問題,實(shí)際上前面兩個(gè)方法等價(jià)于window.t1,可以理解為t1是window的一個(gè)公有屬性,被賦了兩次值,以最后一次賦值為最終值
而后面兩個(gè)方法,可以理解為是t1是個(gè)變量,第四個(gè)方法的var去掉之后的結(jié)果仍然不會(huì)改變
然而,當(dāng)?shù)谒膫€(gè)方法改成function t1(){}這樣的聲明式時(shí),結(jié)果變成了new new new t1,new new new t1,new new t1,new new t1
前面兩個(gè)按照我的理解可以很好的理解為什么是這個(gè)答案,第三個(gè)也可以理解,但是最后一個(gè)輸出讓我比較糾結(jié),希望有高手出現(xiàn)解答一下
另外匿名函數(shù)還有(function(){...})()這樣的寫法,最后一個(gè)括號(hào)用于參數(shù)輸入
還有var t1=new function(){..}這樣的聲明,實(shí)際上t1已經(jīng)是一個(gè)對(duì)象了
例:
var t2 = new function()
{
var temp = 100; //私有成員
this.temp = 200; //公有成員,這兩個(gè)概念會(huì)在第三點(diǎn)以后展開說明
return temp + this.temp;
}
alert(typeof(t2)); //object
alert(t2.constructor()); //300
除此之外,還有使用系統(tǒng)內(nèi)置函數(shù)對(duì)象來構(gòu)建一個(gè)函數(shù),例:
var t3 = new Function('var temp = 100; this.temp = 200; return temp + this.temp;'); //這個(gè)位置加不加new結(jié)果都一樣,WHY
alert(typeof(t3)); //function
alert(t3()); //300
二,創(chuàng)建對(duì)象
首先我們理解一下面向?qū)ο缶幊蹋∣bject-Oriented Programming,OOP),使用OOP技術(shù),常常要使用許多代碼模塊,每個(gè)模塊都提供特定的功能,每個(gè)模塊都是孤立的,甚至與其它模塊完全獨(dú)立
。這種模塊化編程方法提供了非常大的多樣性,大大增加了代碼的重用機(jī)會(huì)??梢耘e例進(jìn)一步說明這個(gè)問題,假定計(jì)算機(jī)上的一個(gè)高性能應(yīng)用程序是一輛一流賽車。如果使用傳統(tǒng)的編程技巧,這輛賽車就是
一個(gè)單元。如果要改進(jìn)該車,就必須替換整個(gè)單元,把它送回廠商,讓汽車專家升級(jí)它,或者購買一個(gè)新車。如果使用OOP技術(shù),就只需從廠商處購買新的引擎,自己按照說明替換它,而不必用鋼鋸切割車體。
不過大部分的論點(diǎn)是,javascript并不是直接的面向?qū)ο蟮恼Z言,但是通過模擬可以做到很多面向?qū)ο笳Z言才能做到的事,如繼承,多態(tài),封裝,javascript都能干(沒有做不到,只是想不到)
///------------------------------------------------------------------------------------------------
//以下三種構(gòu)造對(duì)象的方法
//new Object,實(shí)例化一個(gè)Object
var a=new Object();
a.x=1,a.y=2;
//對(duì)象直接量
var b={x:1,y:2};
//定義類型
function Point(x,y){ //類似于C#中的類
this.x=x;
this.y=y;
}
var p=new Point(1,2); //實(shí)例化類
第一種方法通過構(gòu)造基本對(duì)象直接添加屬性的方法來實(shí)現(xiàn),第二種和第一種差不多,可以看成是第一種方法的快捷表示法
第三種方法中,可以以”類“為基礎(chǔ),創(chuàng)造多個(gè)類型相同的對(duì)象
三,對(duì)象屬性的封裝(公有和私有)
以例子來說明
function List(){
var m_elements=[]; //私有成員,在對(duì)象外無法訪問,如果此處無var聲明,則m_elements將變成全局變量,這樣外部是可以直接訪問到的,如alert(m_elements[0])
m_elements=Array.apply(m_elements,arguments);
//此處模擬getter,使用時(shí)alist.length;
//等價(jià)于getName()方式:this.length=function(){return m_elements.length;},使用時(shí)alist.length();
//公有屬性,可以通過"."運(yùn)算符或下標(biāo)來訪問
this.length={
valueOf:function(){
return m_elements.length;
},
toString:function(){
return m_elements.length;
}
}
//公有方法,此方法使用得alert(alist)相當(dāng)于alert(alist.toString())
this.toString=function(){
return m_elements.toString();
}
//公有方法
this.add=function(){
m_elements.push.apply(m_elements,arguments);
}
//私有方法如下形式,這里涉及到了閉包的概念,接下來繼續(xù)說明
//var add=function()或function add()
//{
//m_elements.push.apply(m_elements,arguments);
/
更多信息請(qǐng)查看IT技術(shù)專欄