日韩欧美国产精品免费一二-日韩欧美国产精品亚洲二区-日韩欧美国产精品专区-日韩欧美国产另-日韩欧美国产免费看-日韩欧美国产免费看清风阁

LOGO OA教程 ERP教程 模切知識(shí)交流 PMS教程 CRM教程 開發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

JS技巧:JavaScript 中的函數(shù)式編程實(shí)踐

admin
2010年8月17日 22:56 本文熱度 4218
基礎(chǔ)知識(shí)

函數(shù)式編程簡介

說到函數(shù)式編程,人們的第一印象往往是其學(xué)院派,晦澀難懂,大概只有那些蓬頭散發(fā),不修邊幅,甚至有些神經(jīng)質(zhì)的大學(xué)教授們才會(huì)用的編程方式。這可能在歷史上的某個(gè)階段的確如此,但是近來函數(shù)式編程已經(jīng)在實(shí)際應(yīng)用中發(fā)揮著巨大作用了,而更有越來越多的語言不斷的加入諸如 閉包,匿名函數(shù)等的支持,從某種程度上來講,函數(shù)式編程正在逐步“同化”命令式編程。

函數(shù)式編程思想的源頭可以追溯到 20 世紀(jì) 30 年代,數(shù)學(xué)家阿隆左 . 丘奇在進(jìn)行一項(xiàng)關(guān)于問題的可計(jì)算性的研究,也就是后來的 lambda 演算。lambda 演算的本質(zhì)為 一切皆函數(shù),函數(shù)可以作為另外一個(gè)函數(shù)的輸出或者 / 和輸入,一系列的函數(shù)使用最終會(huì)形成一個(gè)表達(dá)式鏈,這個(gè)表達(dá)式鏈可以最終求得一個(gè)值,而這個(gè)過程,即為計(jì)算的本質(zhì)。

然而,這種思想在當(dāng)時(shí)的硬件基礎(chǔ)上很難實(shí)現(xiàn),歷史最終選擇了同丘奇的 lambda 理論平行的另一種數(shù)學(xué)理論:圖靈機(jī)作為計(jì)算理論,而采取另一位科學(xué)家馮 . 諾依曼的計(jì)算機(jī)結(jié)構(gòu),并最終被實(shí)現(xiàn)為硬件。由于第一臺(tái)計(jì)算機(jī)即為馮 . 諾依曼的程序存儲(chǔ)結(jié)構(gòu),因此運(yùn)行在此平臺(tái)的程序也繼承了這種基因,程序設(shè)計(jì)語言如 C/Pascal 等都在一定程度上依賴于此體系。

到了 20 世紀(jì) 50 年代,一位 MIT 的教授 John McCarthy 在馮 . 諾依曼體系的機(jī)器上成功的實(shí)現(xiàn)了 lambda 理論,取名為 LISP(LISt Processor), 至此函數(shù)式編程語言便開始活躍于計(jì)算機(jī)科學(xué)領(lǐng)域。

函數(shù)式編程語言特性

在函數(shù)式編程語言中,函數(shù)是第一類的對(duì)象,也就是說,函數(shù) 不依賴于任何其他的對(duì)象而可以獨(dú)立存在,而在面向?qū)ο蟮恼Z言中,函數(shù) ( 方法 ) 是依附于對(duì)象的,屬于對(duì)象的一部分。這一點(diǎn) j 決定了函數(shù)在函數(shù)式語言中的一些特別的性質(zhì),比如作為傳出 / 傳入?yún)?shù),作為一個(gè)普通的變量等。

區(qū)別于命令式編程語言,函數(shù)式編程語言具有一些專用的概念,我們分別進(jìn)行討論:

匿名函數(shù)

在函數(shù)式編程語言中,函數(shù)是可以沒有名字的,匿名函數(shù)通常表示:“可以完成某件事的一塊代碼”。這種表達(dá)在很多場合是有用的,因?yàn)槲覀冇袝r(shí)需要用函數(shù)完成某件事,但是這個(gè)函數(shù)可能只是臨時(shí)性的,那就沒有理由專門為其生成一個(gè)頂層的函數(shù)對(duì)象。比如:


清單 1. map 函數(shù)
   
  function map(array, func){
  var res = [];
  for ( var i = 0, len = array.length; i < len; i++){
 res.push(func(array[i]));
  }
  return res;
 }
 var mapped = map([1, 3, 5, 7, 8],  function (n){
  return n = n + 1;
 });
 print(mapped);
運(yùn)行這段代碼,將會(huì)打印:
 2,4,6,8,9// 對(duì)數(shù)組 [1,3,5,7,8] 中每一個(gè)元素加 1
      


注意 map 函數(shù)的調(diào)用,map 的第二個(gè)參數(shù)為一個(gè)函數(shù),這個(gè)函數(shù)對(duì) map 的第一個(gè)參數(shù) ( 數(shù)組 ) 中的每一個(gè)都有作用,但是對(duì)于 map 之外的代碼可能沒有任何意義,因此,我們無需為其專門定義一個(gè)函數(shù),匿名函數(shù)已經(jīng)足夠。

柯里化

柯里化是把接受多個(gè)參數(shù)的函數(shù)變換成接受一個(gè)單一參數(shù)(最初函數(shù)的第一個(gè)參數(shù))的函數(shù),并且返回接受余下的參數(shù)而且返回結(jié)果的新函數(shù)的技術(shù)。這句話有點(diǎn)繞口,我們可以通過例子來幫助理解:


清單 2. 柯里化函數(shù)
   
function adder(num){
  return
     function (x){
  return num + x;
 }
 }
  var add5 = adder(5);
  var add6 = adder(6);
 print(add5(1));
 print(add6(1));
      


結(jié)果為:

6

7

比較有意思的是:函數(shù) adder 接受一個(gè)參數(shù),并返回一個(gè)函數(shù),這個(gè)返回的函數(shù)可以被預(yù)期的那樣被調(diào)用。變量 add5 保持著 adder(5) 返回的函數(shù),這個(gè)函數(shù)可以接受一個(gè)參數(shù),并返回參數(shù)與 5 的和。

柯里化在 DOM 的回調(diào)中非常有用,我們將在下面的小節(jié)中看到。

高階函數(shù)

高階函數(shù)即為對(duì)函數(shù)的進(jìn)一步抽象,事實(shí)上,我們?cè)谀涿瘮?shù)小節(jié)提到的 map 函數(shù)即為一種高階函數(shù),在很多的函數(shù)式編程語言中均有此函數(shù)。map(array, func) 的表達(dá)式已經(jīng)表明,將 func 函數(shù)作用于 array 中的每一個(gè)元素,最終返回一個(gè)新的 array,應(yīng)該注意的是,map 對(duì) array 和 func 的實(shí)現(xiàn)是沒有任何預(yù)先的假設(shè)的,因此稱之為“高階”函數(shù):


清單 3. 高階函數(shù)
   
function map(array, func){
  var res = [];
  for ( var i = 0, len = array.length; i < len; i++){
   res.push(func(array[i]));
  }
  return res;
 }
 var mapped = map([1, 3, 5, 7, 8],  function (n){
  return n = n + 1;
 });
 print(mapped);
  var mapped2 = map(["one", "two", "three", "four"],
  function (item){
  return "("+item+")";
 });
 print(mapped2);
      


將會(huì)打印如下結(jié)果:

 2,4,6,8,9
 (one),(two),(three),(four)// 為數(shù)組中的每個(gè)字符串加上括號(hào)
      


mapped 和 mapped2 均調(diào)用了 map,但是得到了截然不同的結(jié)果,因?yàn)?map 的參數(shù)本身已經(jīng)進(jìn)行了一次抽象,map 函數(shù)做的是第二次抽象,高階的“階”可以理解為抽象的層次。

JavaScript 中的函數(shù)式編程

JavaScript 是一門被誤解甚深的語言,由于早期的 Web 開發(fā)中,充滿了大量的 copy-paste 代碼,因此平時(shí)可以見到的 JavaScript 代碼質(zhì)量多半不高,而且 JavaScript 代碼總是很飛動(dòng)的不斷閃爍的 gif 廣告,限制網(wǎng)頁內(nèi)容的復(fù)制等聯(lián)系在一起的,因此包括 Web 開發(fā)者在內(nèi)的很多人根本不愿意去學(xué)習(xí) JavaScript。

這種情形在 Ajax 復(fù)興時(shí)得到了徹底的扭轉(zhuǎn),Google Map,Gmail 等 Ajax 應(yīng)用的出現(xiàn)使人們驚嘆:原來 JavaScript 還可以做這樣的事!很快,大量優(yōu)秀的 JavaScript/Ajax 框架不斷出現(xiàn),比如 Dojo,Prototype,jQuery,ExtJS 等等。這些代碼在給頁面帶來絢麗的效果的同時(shí),也讓開發(fā)者看到函數(shù)式語言代碼的優(yōu)雅。

函數(shù)式編程風(fēng)格

在 JavaScript 中,函數(shù)本身為一種特殊對(duì)象,屬于頂層對(duì)象,不依賴于任何其他的對(duì)象而存在,因此可以將函數(shù)作為傳出 / 傳入?yún)?shù),可以存儲(chǔ)在變量中,以及一切其他對(duì)象可以做的事情 ( 因?yàn)楹瘮?shù)就是對(duì)象 )。

JavaScript 被稱為有著 C 語法的 LISP,LISP 代碼的一個(gè)顯著的特點(diǎn)是大量的括號(hào)以及前置的函數(shù)名,比如:


清單 4. LISP 中的加法
   
 (+ 1 3 4 5 6 7)
      


加號(hào)在 LISP 中為一個(gè)函數(shù),這條表達(dá)式的意思為將加號(hào)后邊的所有數(shù)字加起來,并將值返回,JavaScript 可以定義同樣的求和函數(shù):


清單 5. JavaScript 中的求和
   
function sum(){
  var res = 0;
  for ( var i = 0, len = arguments.length; i < len; i++){
 res += parseInt(arguments[i]);
  }
  return res;
 }
 print(sum(1,2,3));
 print(sum(1,2,3,4,6,7,8));
      


運(yùn)行此段代碼,得到如下結(jié)果:

 6
 31
      


如果要完全模擬函數(shù)式編碼的風(fēng)格,我們可以定義一些諸如:


清單 6. 一些簡單的函數(shù)抽象
   
  function add(a, b){  return a+b; }
  function sub(a, b){  return a-b; }
  function mul(a, b){  return a*b; }
  function div(a, b){  return a/b; }
  function rem(a, b){  return a%b; }
  function inc(x){  return x + 1; }
  function dec(x){  return x - 1; }
  function equal(a, b){  return a==b; }
  function great(a, b){  return a>b; }
  function less(a, b){  return a<b; }
      


這樣的小函數(shù)以及謂詞,那樣我們寫出的代碼就更容易被有函數(shù)式編程經(jīng)驗(yàn)的人所接受:


清單 7. 函數(shù)式編程風(fēng)格
   
 // 修改之前的代碼
  function factorial(n){
  if (n == 1){
  return 1;
 } else {
  return factorial(n - 1) * n;
  }
 }
 // 更接近“函數(shù)式”編程風(fēng)格的代碼
  function factorial(n){
     if (equal(n, 1)){
         return 1;
    } else {
         return mul(n, factorial(dec(n)));
    }
 }
      


閉包及其使用

閉包是一個(gè)很有趣的主題,當(dāng)在一個(gè)函數(shù) outter 內(nèi)部定義另一個(gè)函數(shù) inner,而 inner 又引用了 outter 作用域內(nèi)的變量,在 outter 之外使用 inner 函數(shù),則形成了閉包。描述起來雖然比較復(fù)雜,在實(shí)際編程中卻經(jīng)常無意的使用了閉包特性。


清單 8. 一個(gè)閉包的例子
   
function outter(){
  var n = 0;
  return
     function (){
  return n++;
 }
 }
  var o1 = outter();
 o1();//n == 0
 o1();//n == 1
 o1();//n == 2
  var o2 = outter();
 o2();//n == 0
 o2();//n == 1
      


匿名函數(shù) function(){return n++;} 中包含對(duì) outter 的局部變量 n 的引用,因此當(dāng) outter 返回時(shí),n 的值被保留 ( 不會(huì)被垃圾回收機(jī)制回收 ),持續(xù)調(diào)用 o1(),將會(huì)改變 n 的值。而 o2 的值并不會(huì)隨著 o1() 被調(diào)用而改變,第一次調(diào)用 o2 會(huì)得到 n==0 的結(jié)果,用面向?qū)ο蟮男g(shù)語來說,就是 o1 和 o2 為不同的 實(shí)例,互不干涉。

總的來說,閉包很簡單,不是嗎?但是,閉包可以帶來很多好處,比如我們?cè)?Web 開發(fā)中經(jīng)常用到的:


清單 9. jQuery 中的閉包
 var con = $("div#con");
 setTimeout( function (){
 con.css({background:"gray"});
 }, 2000);
      


上邊的代碼使用了 jQuery 的選擇器,找到 id 為 con 的 div 元素,注冊(cè)計(jì)時(shí)器,當(dāng)兩秒中之后,將該 div 的背景色設(shè)置為灰色。這個(gè)代碼片段的神奇之處在于,在調(diào)用了 setTimeout 函數(shù)之后,con 依舊被保持在函數(shù)內(nèi)部,當(dāng)兩秒鐘之后,id 為 con 的 div 元素的背景色確實(shí)得到了改變。應(yīng)該注意的是,setTimeout 在調(diào)用之后已經(jīng)返回了,但是 con 沒有被釋放,這是因?yàn)?con 引用了全局作用域里的變量 con。

使用閉包可以使我們的代碼更加簡潔,關(guān)于閉包的更詳細(xì)論述可以在參考信息中找到。由于閉包的特殊性,在使用閉包時(shí)一定要小心,我們?cè)賮砜匆粋€(gè)容易令人困惑的例子:


清單 10. 錯(cuò)誤的使用閉包
   
  var outter = [];
  function clouseTest () {
  var array = ["one", "two", "three", "four"];
  for ( var i = 0; i < array.length;i++){
  var x = {};
   x.no = i;
   x.text = array[i];
 x.invoke =  function (){
 print(i);
   }
   outter.push(x);
  }
 }
      


上邊的代碼片段很簡單,將多個(gè)這樣的 JavaScript 對(duì)象存入 outter 數(shù)組:


清單 11. 匿名對(duì)象
   
 {
 no : Number,
 text : String,
 invoke :  function (){
 // 打印自己的 no 字段
  }
 }
      


我們來運(yùn)行這段代碼:


清單 12. 錯(cuò)誤的結(jié)果
   
 clouseTest();// 調(diào)用這個(gè)函數(shù),向 outter 數(shù)組中添加對(duì)象
 for ( var i = 0, len = outter.length; i < len; i++){
  outter[i].invoke();
 }
      


出乎意料的是,這段代碼將打印:

 4
 4
 4
 4
      


而不是 1,2,3,4 這樣的序列。讓我們來看看發(fā)生了什么事,每一個(gè)內(nèi)部變量 x 都填寫了自己的 no,text,invoke 字段,但是 invoke 卻總是打印最后一個(gè) i。原來,我們?yōu)?invoke 注冊(cè)的函數(shù)為:


清單 13. 錯(cuò)誤的原因
   
function invoke(){
 print(i);
 }
      


每一個(gè) invoke 均是如此,當(dāng)調(diào)用 outter[i].invoke 時(shí),i 的值才會(huì)被去到,由于 i 是閉包中的局部變量,for 循環(huán)最后退出時(shí)的值為 4,因此調(diào)用 outter 中的每個(gè)元素都會(huì)得到 4。因此,我們需要對(duì)這個(gè)函數(shù)進(jìn)行一些改造:


清單 14. 正確的使用閉包
 var outter = [];
 function clouseTest2(){
  var array = ["one", "two", "three", "four"];
  for ( var i = 0; i < array.length;i++){
  var x = {};
   x.no = i;
   x.text = array[i];
 x.invoke =  function (no){
  return
     function (){
 print(no);
    }
   }(i);
   outter.push(x);
  } 
 }
      


通過將函數(shù) 柯里化,我們這次為 outter 的每個(gè)元素注冊(cè)的其實(shí)是這樣的函數(shù):

 //x == 0
 x.invoke =  function (){print(0);}
 //x == 1
 x.invoke =  function (){print(1);}
 //x == 2
 x.invoke =  function (){print(2);}
 //x == 3
 x.invoke =  function (){print(3);}
      


這樣,就可以得到正確的結(jié)果了。

 

實(shí)際應(yīng)用中的例子

好了,理論知識(shí)已經(jīng)夠多了,我們下面來看看現(xiàn)實(shí)世界中的 JavaScript 函數(shù)式編程。有很多人為使 JavaScript 具有面向?qū)ο箫L(fēng)格而做出了很多努力 (JavaScript 本身具有 可編程性),事實(shí)上,面向?qū)ο蟛⒎潜仨殻褂煤瘮?shù)式編程或者兩者混合使用可以使代碼更加優(yōu)美,簡潔。

jQuery 是一個(gè)非常優(yōu)秀 JavaScript/Ajax 框架,小巧,靈活,具有插件機(jī)制,事實(shí)上,jQuery 的插件非常豐富,從表達(dá)驗(yàn)證,客戶端圖像處理,UI,動(dòng)畫等等。而 jQuery 最大的特點(diǎn)正如其宣稱的那樣,改變了人們編寫 JavaScript 代碼的風(fēng)格。

優(yōu)雅的 jQuery

有經(jīng)驗(yàn)的前端開發(fā)工程師會(huì)發(fā)現(xiàn),平時(shí)做的最多的工作有一定的模式:選擇一些 DOM 元素,然后將一些規(guī)則作用在這些元素上,比如修改樣式表,注冊(cè)事件處理器等。因此 jQuery 實(shí)現(xiàn)了完美的 CSS 選擇器,并提供跨瀏覽器的支持:

清單 15. jQuery 選擇器
   
  var cons = $("div.note");// 找出所有具有 note 類的 div
  var con = $("div#con");// 找出 id 為 con 的 div 元素
  var links = $("a");// 找出頁面上所有的鏈接元素
      


當(dāng)然,jQuery 的選擇器規(guī)則非常豐富,這里要說的是:用 jQuery 選擇器選擇出來的 jQuery 對(duì)象本質(zhì)上是一個(gè) List,正如 LISP 語言那樣,所有的函數(shù)都是基于 List 的。

有了這個(gè) List,我們可以做這樣的動(dòng)作:


清單 16. jQuery 操作 jQuery 對(duì)象 (List)
   
 cons.each( function (index){
 $( this ).click( function (){
 //do something with the node
  });
 });
      


想當(dāng)與對(duì) cons 這個(gè) List中的所有元素使用 map( 還記得我們前面提到的 map 嗎? ),操作結(jié)果仍然為一個(gè) List。我們可以任意的擴(kuò)大 / 縮小這個(gè)列表,比如:


清單 17. 擴(kuò)大 / 縮小 jQuery 集合
   
 cons.find("span.title");// 在 div.note 中進(jìn)行更細(xì)的篩選
 cons.add("div.warn");// 將 div.note 和 div.warn 合并起來
 cons.slice(0, 5);// 獲取 cons 的一個(gè)子集
      


現(xiàn)在我們來看一個(gè)小例子,假設(shè)有這樣一個(gè)頁面:


清單 18. 頁面的 HTML 結(jié)構(gòu)
   
 <div class="note">
 <span class="title">Hello, world</span>
 </div>
 <div class="note">
 <span class="title">345</span>
 </div>
 <div class="note">
 <span class="title">Hello, world</span>
 </div>
 <div class="note">
 <span class="title">67</span>
 </div>
 <div class="note">
 <span class="title">483</span>
 </div>
      


效果如下:


圖 1. 過濾之前的效果
 

我們通過 jQuery 對(duì)包裝集進(jìn)行一次過濾,jQuery 的過濾函數(shù)可以使得選擇出來的列表對(duì)象只保留符合條件的,在這個(gè)例子中,我們保留這樣的 div,當(dāng)且僅當(dāng)這個(gè) div 中包含一個(gè)類名為 title 的 span,并且這個(gè) span 的內(nèi)容為數(shù)字:


清單 19. 過濾集合
   
 var cons = $("div.note").hide();// 選擇 note 類的 div, 并隱藏
 cons.filter( function (){
  return $( this ).find("span.title").html().match(/^\d+$/);
 }).show();
      


效果如下圖所示:


圖 2. 過濾之后的效果
 

我們?cè)賮砜纯?jQuery 中對(duì)數(shù)組的操作 ( 本質(zhì)上來講,JavaScript 中的數(shù)組跟 List 是很類似的 ),比如我們?cè)谇懊娴睦又刑岬降?map 函數(shù),過濾器等:


清單 20. jQuery 對(duì)數(shù)組的函數(shù)式操作
   
 var mapped = $.map([1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
  function (n){
  return n + 1;
 });
  var greped = $.grep([1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
  function (n){
  return n % 2 == 0;
 });
      


mapped 將被賦值為 :

 [2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
      


而 greped 則為:

 [2, 4, 6, 8, 10]
      


我們?cè)賮砜匆粋€(gè)更接近實(shí)際的例子:


清單 21. 一個(gè)頁面刷新的例子
   
function update(item){
  return
     function (text){
 $("div#"+item).html(text);
  }
 }
 function refresh(url, callback){
  var params = {
 type : "echo",
 data : ""
  };
 $.ajax({
 type:"post",
   url:url,
 cache: false ,
 async: true ,
 dataType:"json",
   data:params,
 
 success:  function (data, status){
    callback(data);
   },
 
 error:  function (err){
 alert("error : "+err);
   }
  });
 }
 refresh("action.do/op=1", update("content1"));
 refresh("action.do/op=2", update("content2"));
 refresh("action.do/op=3", update("content3"));
      


首先聲明一個(gè)柯里化的函數(shù) update,這個(gè)函數(shù)會(huì)將傳入的參數(shù)作為選擇器的 id,并更新這個(gè) div 的內(nèi)容 (innerHTML)。然后聲明一個(gè)函數(shù) refresh,refresh 接受兩個(gè)參數(shù),第一個(gè)參數(shù)為服務(wù)器端的 url,第二個(gè)參數(shù)為一個(gè)回調(diào)函數(shù),當(dāng)服務(wù)器端成功返回時(shí),調(diào)用該函數(shù)。

然后我們陸續(xù)調(diào)用三次 refresh,每次的 url 和 id 都不同,這樣可以將 content1,content2,conetent3 的內(nèi)容通過異步方式更新。這種模式在實(shí)際的編程中相當(dāng)有效,因?yàn)殛P(guān)于如何與服務(wù)器通信,以及如果選取頁面內(nèi)容的部分被很好的抽象成函數(shù),現(xiàn)在我們需要做的就是將 url 和 id 傳遞給 refresh,即可完成需要的動(dòng)作。函數(shù)式編程在很大程度上降低了這個(gè)過程的復(fù)雜性,這正是我們選擇使用該思想的最終原因。

結(jié)束語

實(shí)際的應(yīng)用中,不會(huì)囿于函數(shù)式或者面向?qū)ο螅ǔJ莾烧呋旌鲜褂茫聦?shí)上,很多主流的面向?qū)ο笳Z言都在不斷的完善自己,比如加入一些函數(shù)式編程語言的特征等,JavaScript 中,這兩者得到了良好的結(jié)合,代碼不但可以非常簡單,優(yōu)美,而且更易于調(diào)試。

文中僅僅提到 jQuery 特征的一小部分,如果感興趣,則可以在參考資料中找到更多的鏈接,jQuery 非常的流行,因此你可以找到很多論述如何使用它的文章。

 

參考資料

•jQuery官方網(wǎng)站的地址,可以下載到最新的 jQuery 庫。


•JavaScript 中的閉包:一篇優(yōu)秀的關(guān)于 JavaScript 閉包的論述。


•文中提到的 LISP 之根源的譯文,該文詳細(xì)的描述了 LISP 的其中基本原語,很好的解釋了 LISP 的 可編程性。


•函數(shù)式編程的基本概念:一篇關(guān)于 JavaScript 函數(shù)式編程的基本概念的文章。


•“JavaScript 框架比較”:在本文中,您將了解如何通過 JavaScript 框架更輕松、更快速地創(chuàng)建具有高度交互性和響應(yīng)性的 Web 站點(diǎn)和 Web 應(yīng)用程序。


•“JavaScript 開發(fā)工具包 ”:本專題為您收集了一些和目前業(yè)界比較流行的 JavaScript 開發(fā)工具包相關(guān)的資源,從初級(jí)的入門介紹到高級(jí)的使用以及和其他開發(fā)語言、軟件集成的內(nèi)容。


•developerWorks 技術(shù)活動(dòng)和網(wǎng)絡(luò)廣播:隨時(shí)關(guān)注 developerWorks 技術(shù)活動(dòng)和網(wǎng)絡(luò)廣播。


•developerWorks Web development 專區(qū):通過專門關(guān)于 Web 技術(shù)的文章和教程,擴(kuò)展您在網(wǎng)站開發(fā)方面的技能。


•developerWorks Ajax 資源中心:這是有關(guān) Ajax 編程模型信息的一站式中心,包括很多文檔、教程、論壇、blog、wiki 和新聞。任何 Ajax 的新信息都能在這里找到。


•developerWorks Web 2.0 資源中心,這是有關(guān) Web 2.0 相關(guān)信息的一站式中心,包括大量 Web 2.0 技術(shù)文章、教程、下載和相關(guān)技術(shù)資源。您還可以通過 Web 2.0 新手入門 欄目,迅速了解 Web 2.0 的相關(guān)概念。

關(guān)于作者

邱俊濤,畢業(yè)于昆明理工大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)專業(yè),對(duì)機(jī)械控制、電子、人工智能等方面有濃厚的興趣,對(duì)計(jì)算機(jī)科學(xué)的底層比較熟悉。喜歡 C/Java/Python 等語言。

該文章在 2010/8/17 22:56:34 編輯過
關(guān)鍵字查詢
相關(guān)文章
正在查詢...
點(diǎn)晴ERP是一款針對(duì)中小制造業(yè)的專業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國內(nèi)大量中小企業(yè)的青睞。
點(diǎn)晴PMS碼頭管理系統(tǒng)主要針對(duì)港口碼頭集裝箱與散貨日常運(yùn)作、調(diào)度、堆場、車隊(duì)、財(cái)務(wù)費(fèi)用、相關(guān)報(bào)表等業(yè)務(wù)管理,結(jié)合碼頭的業(yè)務(wù)特點(diǎn),圍繞調(diào)度、堆場作業(yè)而開發(fā)的。集技術(shù)的先進(jìn)性、管理的有效性于一體,是物流碼頭及其他港口類企業(yè)的高效ERP管理信息系統(tǒng)。
點(diǎn)晴WMS倉儲(chǔ)管理系統(tǒng)提供了貨物產(chǎn)品管理,銷售管理,采購管理,倉儲(chǔ)管理,倉庫管理,保質(zhì)期管理,貨位管理,庫位管理,生產(chǎn)管理,WMS管理系統(tǒng),標(biāo)簽打印,條形碼,二維碼管理,批號(hào)管理軟件。
點(diǎn)晴免費(fèi)OA是一款軟件和通用服務(wù)都免費(fèi),不限功能、不限時(shí)間、不限用戶的免費(fèi)OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved

主站蜘蛛池模板: 日韩女优在线观看 | 视频免费看 | 国产精产国品一二三在观看 | 资源在线观看高清国产 | 免费成年人看的视 | 日本黄页网站在线观看 | 999y| 国产在线一区二区三区视频 | 亚洲a∨ | 巨熟乳波霸中文观看免费 | 野外性史| 在线亚洲欧美日韩每日更新 | 免费国产网站在线观看不卡 | 国产高清在线视频伊甸园 | 一区二区在 | 亚洲国产欧洲在线一区 | 免费福利影视 | 精品免费国产一区二区三区四区五 | 九热视频 | 日本xxx在线观看免费播放 | 国产精品网站 | 免费在线观看的网站 | 欧美另类吹潮 | 亚洲日本欧美日韩髙清观看 | 亚洲欧美日本a∨在 | 欧美三级短视频 | ⅴ在线观看 | 亚洲天堂一区二区在线观看 | 欧美亚洲综合成人a∨在线 亚洲国产中文字幕在线观看 | 亚洲图片偷拍视频区 | 91一区二区午夜免费 | 欧洲亚洲一区二区三区 | 亚洲成年看片在线观看男男 | 老司机午夜精 | 国产精品欧美一区二区 | 99视频精品全部品全正 | 日本激情夜里视频在线观看 | 亚洲第一成人影院 | 欧美一区二区三区精品视频在线 | 亚洲欧洲日韩国产aa色大片 | 国产拍偷精品网最新在线观 |