JavaScript筆記

JavaScript 的成功讓人津津樂道,爲 Web 網頁編寫 JavaScript 代碼已經是所有 Web 設計師的基本功,這門有趣的語言蘊藏着許多不爲人熟知的東西,即使多年的 JavaScript 程序員,也未能完全吃透。本文從7個方面講述 JavaScript 中那些你不很熟知但非常實用的技巧。

簡略語句

JavaScript 可以使用簡略語句快速創建對象和數組,比如下面的代碼:

var car = new Object();
car.colour = 'red';
car.wheels = 4;
car.hubcaps = 'spinning';
car.age=4;

可以使用簡略語句如下:

var car = {
  colour:'red',
  wheels:4,
  hubcaps:'spinning',
  age:4
}


對象 car 就此創建,不過需要特別注意,結束花括號前一定不要加 ";" 否則在 IE 會遇到很大麻煩。

創建數組的傳統方法是:


var moviesThatNeedBetterWriters = new Array(
  'Transformers','Transformers2','Avatar','Indiana Jones 4'
);


使用簡略語句則:

var moviesThatNeedBetterWriters = [
 'Transformers','Transformers2','Avatar','Indiana Jones 4'
];


另一個可以使用簡略語句的地方是條件判斷語句:

var direction;
if(x < 200){
 direction = 1;
} else {
 direction = -1;
}



可以簡略爲:

var direction = x < 200 ? 1 : -1;


JSON 數據格式

JSON 是 "JavaScript Object Notation" 的縮寫,由 Douglas Crockford 設計,JSON 改變了 JavaScript 在緩存複雜數據格式方面的困境,如下例,假如你要描述一個樂隊,可以這樣寫

var hand = {
 "name":"The Red Hot Chili Peppers",
 "members":[
  {
   "name":"Anthony Kiedis",
   "role":"lead vocals"
  },
  {
   "name":"Michael 'Flea' Balzary",
   "role":"bass guitar, trumpet, backing vocals"
  },
  {
   "name":"Chad Smith",
   "role":"drums,percussion"
  },
  {
   "name":"John Frusciante",
   "role":"Lead Guitar"
  }
 ],
 "year":"2009"
}



你可以在 JavaScript 中直接使用 JSON,甚至作爲某些 API 的返回數據對象,以下代碼調用著名書籤網站 delicious.com 的一個 API,返回你在該網站的所有書籤,並顯示在你自己的網站:

<div id="delicious"></div>
<mce:script type="text/javascript"><!--
function delicious(o){
 var out = '<ul>';
 for(var i=0;i<o.length;i++){
  out += '<li><a href="' + o[i].u+'" mce_href="' + o[i].u+'">' + o[i].d + '</a></li>';
 }
 out += '</ul>';
 document.getElementById('delicious').innerHTML = out;
}
// --></mce:script>
<mce:script src="http://feeds.delicious.com/v2/json/codepo8/javascript?count=15&callback=delicious" mce_src="http://feeds.delicious.com/v2/json/codepo8/javascript?count=15&callback=delicious"></mce:script>




JavaScript 本地函數 (Math, Array 和 String)

JavaScript 有很多內置函數,有效的使用,可以避免很多不必要的代碼,比如,從一個數組中找出最大值,傳統的方法是:


var numbers = [3,342,23,22,124];
var max = 0;
for(var i=0;i<numbers.length;i++){
 if(numbers[i] > max){
  max = numbers[i];
 }
}
alert(max);


使用內置函數可以更容易實現:

var numbers = [3,342,23,22,124];
numbers.sort(function(a,b){return b-a});
alert(numbers[0]);




另一個方法是使用 Math.max() 方法:

Math.max(12,123,3,2,433,4); // returns 433




你可以用這個方法幫助探測瀏覽器

var scrollTop = Math.max(
 doc.documentElement.scrollTop,
 doc.body.scrollTop
);


這解決了 IE 瀏覽器的一個問題,通過這種方法,你總是可以找到那個正確的值,因爲瀏覽器不支持的那個值會返回 undefined。



還可以使用 JavaScript 內置的 split() 和 join() 函數處理 HTML 對象的 CSS 類名,如果 HTML 對象的類名是空格隔開的多個名字,你在爲它追加或刪除一個 CSS 類名的時候需要特別注意,如果該對象還沒有類名屬性,可以直接將新的類名賦予它,如果已經存在類名,新增的類名前必須有一個空格,用傳統的 JavaScript 方法是這樣實現的:

function addclass(elm,newclass){
 var c = elm.className;
 elm.className = (c === '') ? newclass : c+' '+newclass;
}


使用 split 和 join 方法則直觀優雅得多:

function addclass(elm,newclass){
 var classes = elm.className.split(' ');
 classes.push(newclass);
 elm.className = classes.join(' ');
}


事件代理

與其在 HTML 文檔中設計一堆事件,不如直接設計一個事件代理,舉例說明,假如你有一些鏈接,用戶點擊後不想打開鏈接,而是執行某個事件,HTML 代碼如下:


<h2>Great Web resources</h2>
<ul id="resources">
 <li><a href="http://opera.com/wsc" mce_href="http://opera.com/wsc">Opera Web Standards Curriculum</a></li>
 <li><a href="http://sitepoint.com" mce_href="http://sitepoint.com">Sitepoint</a></li>
 <li><a href="http://alistapart.com" mce_href="http://alistapart.com">A List Apart</a></li>
 <li><a href="http://yuiblog.com" mce_href="http://yuiblog.com">YUI Blog</a></li>
 <li><a href="http://blameitonthevoices.com" mce_href="http://blameitonthevoices.com">Blame it on the voices</a></li>
 <li><a href="http://oddlyspecific.com" mce_href="http://oddlyspecific.com">Oddly specific</a></li>
</ul>



傳統的事件處理是遍歷各個鏈接,加上各自的事件處理:

// Classic event handling example
(function(){
 var resources = document.getElementById('resources');
 var links = resources.getElementsByTagName('a');
 var all = links.length;
 for(var i=0;i<all;i++){
  // Attach a listener to each link
  links[i].addEventListener('click',handler,false);
 };
 function handler(e){
  var x = e.target; // Get the link that was clicked
  alert(x);
  e.preventDefault();
 };
})();



使用事件代理,可以直接處理,無需遍歷:


(function(){
 var resources = document.getElementById('resources');
 resources.addEventListener('click',handler,false);
 function handler(e){
  var x = e.target;
  if(x.nodeName.toLowerCase() === 'a'){
   alert('Event delegation:' + x);
   e.preventDefault();
  }
 };
})();



匿名函數與 Module 模式

JavaScript 的一個問題是,任何變量,函數或是對象,除非是在某個函數內部定義,否則,就是全局的,意味着同一網頁的別的代碼可以訪問並改寫這個變量(ECMA 的 JavaScript 5 已經改變了這一狀況 - 譯者),使用匿名函數,你可以繞過這一問題。

比如,你有這樣一段代碼,很顯然,變量 name, age, status 將成爲全局變量

var name = 'Chris';
var age = '34';
var status = 'single';
function createMember(){
 // [...]
}
function getMemberDetails(){
 // [...]
}




爲了避免這一問題,你可以使用匿名函數:

var myApplication = frunction(){
 var name = 'Chris';
 var age = '34';
 var status = 'single';
 function createMember(){
  // [...]
 }
 function getMemberDetails(){
  // [...]
 }
}();



如果這個函數不會被調用,可以更直接爲:

(function(){
 var name = 'Chris';
 var age = '34';
 var status = 'single';
 function createMember(){
   // [...]
 }
 function getMemberDetails(){
   // [...]
 }
})();



如果要訪問其中的對象或函數,可以:

var myApplication = function(){
 var name = 'Chris';
 var age = '34';
 var status = 'single';
 return{
  createMember:function(){
   // [...]
  }
  getMemberDetails:function(){
   // [...]
  }
 }
}();
// myApplication.createMember() and
// myApplication.getMemberDetails() now works.




這就是所謂 Module 模式或單例模式(Singleton),該模式爲 Douglas Crockford 所推崇,並被大量應用在 Yahoo User Interface Library YUI 。

假如你想在別的地方調用裏面的方法,又不想在調用前使用 myApplication 這個對象名,可以在匿名函數中返回這些方法,甚至用簡稱返回:

var myApplication = function(){
 var name = 'Chris';
 var age = '34';
 var status = 'single';
 function createMember(){
  // [...]
 }
 function getMemberDetails(){
  // [...]
 }
 return{
  create:createMember,
  get:getMemberDetails
 }
}();
//myApplication.get() and myApplication.create now work.



代碼配置

別人使用你編寫的 JavaScript 代碼的時候,難免會更改某些代碼,但這會很困難,因爲不是每個人都很容易讀懂別人的代碼,與其這樣,不如創建一個代碼配置對象,別人只需要在這個對象中更改某些配置即可實現代碼的更改。這裏有一篇 JavaScript 配置對象詳解 的文章,簡單說:
在代碼中創建一個叫做 configuration 的對象
裏面保存所有可以更改的配置,如 CSS ID 和類名,按鈕的標籤文字,描述性文字,本地化語言設置
將該對象設置爲全局對象,以便別人直接訪問並改寫

你應當在最後一步做這項工作,這裏有一個文章,交付代碼前的5件事 值的參考。


同後臺交互

JavaScript 是一門前臺語言,你需要別的語言同後臺交互,並返回數據,使用 AJAX,你可以讓 JavaScript 直接使用同後臺的交互,將複雜的數據處理交由後臺處理。


JavaScript 框架

自己編寫適應各種瀏覽器的代碼是完全浪費時間,應當選擇一個 JavaScript 框架,讓這些複雜的事情交給框架處理。



更多資源
Douglas Crockford on JavaScript
JavaScript 深度視頻教程
The Opera Web Standards Curriculum
JavaScript 詳解




這裏還有一篇 有關 JavaScript 的 10 件讓人費解的事情

http://www.comsharp.com/GetKnowledge/zh-CN/It_News_K902.aspx



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章