Javascript中的內定屬性與函式: arguments, callee, caller, this, apply(), call()

September 1st, 2010

arguments, caller, callee都是用在函式(function)內的特殊內定屬性(Attribute)。而apply()及call()都是用來呼叫函式的不同作法。

  • arguments
    可用來取得function傳入的實際變數Array。這個變數特別適合用在撰寫”多形”(Polymorphism)函式上,即可以根據不同的傳入參數做不同的處理。
    範例一 – 加總函式

    function sum() {
    	var total = 0;
    	for( var i=0; i<arguments.length; i++ ) {
    		total += arguments[i];
    	}
    	return total;
    }
    
    // 測試
    log( sum() );                              // 結果 = 0
    log( sum(1, 2) );                          // 結果 = 3
    log( sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) ); // 結果 = 55
    

    範例二 – 自我介紹函式

    function introduce() {
    	var callback = null;
    	var msg = '';
    	for( var i=0; i<arguments.length; i++ ) {
    		var p = arguments[i];
    		if( typeof p == 'string' ) {
    			msg += '我叫'+p;
    		} else if( typeof p == 'number' ) {
    			msg += '今年'+p+'歲';
    		} else if( typeof p == 'function' ) {
    			callback = p;
    		}
    	}
    
    	if( callback != null ) {
    		callback(msg);
    	} else {
    		log( msg );
    	}
    }
    
    // 測試2
    introduce('David');                    // console印出"我叫David"
    introduce('David', 29);                // console印出"我叫David今年29歲"
    introduce('David', function(msg) {     // 跳出"我叫David"的訊息
    	alert(msg);
    });
    introduce('David', 29, function(msg) { // 跳出"我叫David今年29歲"的訊息
    	alert(msg);
    });
    
  • callee
    此為arguments的屬性之一,可取得被call function本身。
  • caller
    可用來取得call該function的來源物件。
  • this
    指到函數的擁有者(Owner)。
  • apply()與call()
    apply與call兩者本身的功能相同,都可以用來特別指定被call function中的this變數。
    不同之處在於傳入參數的寫法不同:

    apply( thisArg, argArray ); // 第二個參數必須是個Array,否則會產生參數型態錯誤的Error
    call( thisArg[, arg1, arg2…] );

以下範例將秀出callee, caller, this及apply(), call()的用法

function methodA(p1, p2, p3) {
	log('========================');
	log( arguments ); // 實際傳入的參數陣列
	log( arguments.callee ); // 指到methodA
	log( arguments.callee.caller ); // 指到call methodA的object
	log( '宣告參數長度: '+arguments.callee.length );
	log( '實際參數長度: '+arguments.length );
	log( this );
	log( p1 );
	log( p2 );
	log( p3 );
}

function handleCaller() {
	methodA('xxx', 'yyy');
	methodA.apply(handleCaller, ['xxx', 'yyy']); // 指定this object
}

function init() {
	handleCaller();
	methodA.call(handleCaller, 'xxx', 'yyy'); // 指定this object
}
init();

結果:
注意到第一個結果區塊的this指到window物件了,而其它兩個執行結果則指到handleCaller
而第三個結果區塊的function caller指到init,其它兩個執行結果則指到handleCaller

以上範例中會使用到的 log function – 用於輸出文字到Firebug或Chrome, IE8的console

function log(msg) {
	if( window.console ) {
		console.log(msg);
	}
}

參考:
http://www.ijavascript.cn/jiaocheng/caller-callee-call-apply-464.html
http://blog.darkthread.net/blogs/darkthreadtw/archive/2009/03/11/js-this-and-closure.aspx
http://blog.darkthread.net/blogs/darkthreadtw/archive/2009/04/10/js-func-apply.aspx

Web Page裡的三個維度

August 30th, 2010

看完這段介紹”什麼是Front-end Engineer及其重要性”的影片後,裡面有講到一些Web Page設計上的重點,在此記錄一下以免忘記。


Nate Koechley: "Professional Frontend Engineering" @ Yahoo! Video

一般的Web Page都會包含HTML, CSS, Javascript三個部份。彼此之間有些角色定位模糊的地方,究竟該怎麼切分工呢? 請看以下定義:

HTML

定義頁面的內容與結構(What)。Developer應該要避免使用過多的div或span,取而代之的,應該使用更有意義的tag去包裝。而一個好的設計,不應該在HTML裡寫任何Javascript code,而改用動態綁定方式。

不好的寫法範例:
<a href=”test.html” onclick=”javascript:onClick(this);”>

CSS

決定頁面文容該如何呈現(How)。在不同Browser的呈現結果可能會差很多,因此,Developer一定要在要支援的Browser平台上實際測試過。通常IE系列的Browser會跟其它(Firefox, Chrome, Safari, Opera…etc.)差很多… :evil:

Javascript

定義頁面的行為(Why)。例用動態綁定event去處理各種element UI行為,並且使用物件導向的設計,使程式碼更好維護與修改。有關物件導向的Javscript設計,可以參考這幾篇:
http://msdn.microsoft.com/zh-tw/magazine/cc163419.aspx
http://fstoke.me/blog/?page_id=1610

HTML標準中不常用但對SEO有用的語法

August 30th, 2010

別人傳給我看的,覺得不錯把它記起來…

  1. h1的合理使用,<h1>到<h6>表示標題的6個級別-重要性從高到低,如果在設計網頁過程中,你覺得他的默認外觀不好看,可以通過css輕鬆設置你想要的樣式。依照W3C的規定,標題跳級不是好的做法,因為h1-h6就像是一個大綱,要保持各個級別的連貫順序。
  2. <table>裡面不常用的一些標籤:<caption>表格的標題,<table summary=”摘要”>表格摘要,<th>表頭,<td headers=”">表頭與數據的關係,< th abbr=”">改變語音合成器讀出的內容,<thead>表頭,<tfoot>表腳,<tbody>表體。
  3. 表格並非結構,在某些用途上是不可替代的,所以請不要絞盡腦汁用div代替table。
  4. <blockquote>表示引用文本,當引用外界文字時,盡量用該標記
  5. <lable>標籤標記,用來標註表單控件
  6. <dl><dt>來定義列表,在構建提交表單時,可以用該語法來代替<p>或者<table>等
  7. <input tabindex=1>讓用戶使用鍵盤來移動表單控件的當前焦點
  8. <lable for=”name” accesskey=”9″>Name:</lable><input type=”text” id=”name” name=”name”>用戶可以用Ctrl或者Alt鍵加上我們在代碼中設置的9鍵,來切換焦點到這個輸入框內。
  9. 在<form>中用<fieldset>將表單內容分組,當加上描述符<legend>之後,大多數瀏覽器上,都會在所分組的控件外圍顯示一條邊框。
  10. <strong>和<em>比<b>和<i>要好,因為前兩者是表達意義,而後兩者是表達外觀。em表示強調,strong表示更加強調。
  11. W3C 在Html4.01規範中還定義了下列短語元素:
    <cite>包含引用信息或者對其他來源的參考說明;
    <dfn>表示所包含的是術語的定義。
    <code>指名一段計算機程序代碼。
    <samp>指明一段程序或者腳本等的輸出。
    <kdb>表示由用戶輸入的文本。
    <var>表示一個變量或者程序參數的實例。
    <abbr>表示一種簡寫形式,例如 WWW。
    <acronym>表示只取首字母的縮寫形式,例如WAC。
  12. 更好的錨點方法
    <p><a href=”#oranges”>關於桔子</a></p>
    … 文字 …
    <a id=”oranges” name=”oranges”>桔子很可口</a>
    … 更多的文字 …
  13. 給錨點加上title屬性可以為這個鏈接所指向的目標提供豐富和明確的描述信息。
  14. 更多的列表,無序的列表使用<ul><li>,有序的列表使用<ol><li>,定義列表使用<dl><dt>(詞條)<dd>(解釋),你可以通過css中的list-style-type來改變它們的樣式,甚至做到自定義,decimal數字型,upper-alpha大寫字母型,lower-alpha小寫字母型,upper-roman大寫羅馬數字,lower- roman小寫羅馬數字,none不顯示。

精簡HTML:使用class來定義樣式;使用css的#來定義樣式;去掉不必要的<div>