2014年6月25日 星期三

Javascript Enlightment Memo 深入精要筆記

Chapter 1 - Javascript物件

* Function接(),會產生一個執行物件(function return後如無參考,則會被GC),並會傳回這個function的return value
* Function冠用new(此時稱此function為建構函式),會產生一個執行物件,並傳回這個物件
* function(){return {ID: 1}}() 跟 new function(){this.ID = 1} 都會傳回一個物件,差別是前者不會有prototype繼承
  - 是嘛?在Chrome裡都有耶? 
* 尚未明白為何的地方:
  - Function裏面有return,執行物件可以接()執行!!
  - Function沒有return,就只是執行物件

* 九大原生物件
  - Number, String, Boolean, Array, Object, Function, RegExp, Date, Error
* 原生物件標準需由new運算子產生,但可用字面值(Literal)來產生
  - var n = 1
  - var s = "string"
  - var b = true
  - var a = [1,2,3]
  - var o = {ID: 1}
  - var f = function(){}
  - var r = /.*/

* 值分為原始值(Simple Value)與複合值(Complex Value)
  - 原始值
    - 複製:完全複製
    - 比較:比較其值
    - 屬性:沒這檔事
  - 複合值(就像指標啦)
    - 複製:僅複製參考
    - 比較:比較參考
    - 屬性:可以加入屬性

* 原始值包括6類:
  - null
  - undefined
  - "string"(雙引號字串)
  - 123(單純的數字)
  - true
  - false

* 當使用Literal產生Number, String, Boolean時,得到的是原始值(Simple value)

* Number, String, Boolean
  - 需特別注意當產生方式不同時(原始值/複合值),行為有所不同

* 物件的Constructor是"指向"他的建構函數
  - 所以判斷物件類型的方法之一是比對Constructor是否為某個函數


Chapter 2 - 應用物件與屬性

* Complex Value的屬性可以是大部分的js value

* 可以亂裝(就JSON)

* 屬性可以透過obj.prop或obj['prop']存取
 - 括號法功能較強:
    - 屬性名稱可以由字串組合
    - 屬性名稱可為數字或保留字, ex:  obj['123'], obj['object']
* 從物件中移除屬性用delete

* 尋找屬性:原型鍊(Prototype Chain) (就是繼承鍊!)
  0. 目前物件為obj
  1. 先找obj下面
  2. 再找obj.constructor.prototype
  3. 再找obj.constructor.constructor.prototype
  4. 都沒有,回傳undefined

* hasOwnProperty() v.s. in 運算元  (注意屬性在此是以名稱(字串啦)來詢問)
  - hasOwnProperty()
    - 若為true,表示屬性不是從原型鍊來的。
  - in
    - 若為true,表示該物件的原型鍊找的到該屬性。

* 尋訪屬性,可使用 for-in loop
  - 會列出包含原型鍊內的所有屬性。可用 hasOwnProperty()檢查
  - 只會列出可列舉的(enumerable)的屬性,可用propertyIsEnumerable()檢查

* Host物件
  - 非javascript標準內的物件,ex. 瀏覽器提供的,
  - 其中必有一個Head物件,也就是環境物件, ex. window


Chapter 3 - Object()

* new Object()可填initial value,物件會成為該value所屬原生物件的物件

* 繼承鍊的源頭Object.prototype (注意Object不是實體)


Chapter 4 - Function()

* 函數:一個陳述式的執行範圍

* 在函數名稱後加上()代表執行此函數

* new Function(arg1,...., argn),可吃n個參數,前面是建構出的Function的參數,最後一個是函數內容的字串
  - var func = new Function('a', 'b', 'return a+b')
  - var func = function(a, b) {return a+b}

* 上面那種作法會用到eval()造成運算浪費

* 沒有指定return的函式會回傳undefined

* arguments
  - 所以函數可以不給定指定的參數
  - 也可以給沒指定的參數
  - arguments.callee指向函數本身
  - arguments.length是函數被呼叫時得到的參數量 (1.4之後Deprecated,只能arguments.callee.length取得函數指定的參數數量)

* this
  - 這個函數屬於那個物件
  - 若是Global,則指向環境物件

* length
  - var func = function(a, b , c){} 則 func.length === 3
* 函數建立4種方式
  - var funcConstructor = new Function('a', 'b', 'return a+b');
  - function funcStatement(a, b) { return a+b; }
  - var funcExpression = function(a, b) { return a + b; }
  - var funcNamedFunction = function funcNamedFunction(a, b) { return a + b; }

* 函式使用4種方式
  - 當函式執行,就是加上()來執行
  - 當方法執行,一樣是()
  - 當建構式使用,配合new
  - apply()或call(),用途是改變所屬物件(也就是this)

* function aaa(){} 沒有aaa就叫匿名函式

* 可以無限巢狀

* 函式可以當作參數傳入函式,也可以當作return value被回傳

* Javascript執行前會解譯程式,所以可以在函式宣告之前使用函式

* 函式可以遞迴呼叫


Chapter 5 - Head/Global 物件

* Head物件包含所有的物件,透過範圍鍊所有地方都可以呼叫Head物件的成員,故就像全域屬性一樣

* 參考Head物件
  - 直接參考其名稱(ex. 瀏覽器是window)
  - 在全域範圍內使用this

* 在全域範圍中進行宣告,用var不用var有些微差異
  - 用var 是屬性
  - 不用  是變數

* 因為Head是範圍鏈的最後一站,所以他可以是隱式的。通常使用Head物件的成員不會明確參考Head物件
  - window.alert()
  - alert()  <-- br="" clear="none" usually="">


Chapter 6 - this關鍵字

* this參考到函式所在的物件
  - 例外:使用new、apply()、call()

* 巢狀函式內,this
  - ES3:this會迷失,而指到Head
  - ES5:會正常指到應該的物件

* 常用that來避免this迷失

* apply()跟call()可以指定this的值

* 當使用new呼叫函式時,this會參考到等等要被new出來的物件
  - 如果不用new呼叫,那就會在函式所屬物件產生新的屬性。(通常就是window了XD)

* 在prototype中的函式參考到this,this會指向實際的instance,而不是prototype


Chapter 7 - 範圍與Closure

* Javascript的Scope有:
  - 全域範圍
  - 函式範圍
  - eval()範圍

* Javascript沒有區塊範圍( {} )

* 以var宣告的變數會是在當前範圍內宣告,沒有用var宣告的會被宣告在全域範圍

* 若同樣的變數名稱在不同的範圍內,會傳回最近的那個值

* 範圍鍊是在"定義"函式時決定的,而非在呼叫過程中決定
  - 這就叫作語彙範圍(Lexical Scoping)


Chapter 8 - 函式原型屬性


* 預設的prototype是一個Object()物件

* Firefox2+/Safari/Chrome可以這樣參考prototype
  - obj.__proto__

* EMCA標準參考方式
  - obj.constructor.prototype

* Prototype鍊會傳回第一個找到的屬性,所以會有屏蔽效應

* 若是修改A物件預設的prototype,那用A物件new出來的物件其constructor不會是A(),而是Object()
  - 要避免必須在a的prototype內加入constructor為a

* prototype鍊是動態參考的,所以當你修改了prototype的內容,所有的Instances都會參考到最新的內容

* 但若直經更換整個prototype,現有的Instances還是會參考到舊的prototype

* 一旦建立Instances了,就不該更換prototype,避免物件有不一致的行為

* prototype繼承鍊的原始用意是要摹仿傳統物件導向的繼承機制


Chapter 9 - Array()


* Array(1,2,3)會建立一個長度為3且初始值分別為1,2,3的陣列
  但Array(5)則會建立一個長度為5的空陣列

* 透過更改length屬性,會讓Array實質的長大或變小

* 陣列裏面可以存放陣列,而有多維陣列的行為

* 向後尋訪陣列
  var count = 0
  while (count < arr.length){
    count++;
  }

* 向前尋訪陣列
  var count = arr.length
  while(count--) {
  }


Chapter 10 - String()

* a = "abc"; typeof a是String
  a = new String("abc"); typeof a是Object  (!!!!)


Chapter 11 - Number()

* 第1點跟String一樣,請使用Literal產生Number避免typeof變成Object

* 可以使用hex或oct表達法
  - var a = 0xff   //a = 255
  - var b = 012  //a = 10


Chapter 12 - Boolean()

* 第1點,一樣, String()/Number()/Boolean()都有這個問題

* var a = new Boolean(false); console.log( a ? "true" : "false"); 會log true。WTF

* 0, -0, null, false, NaN, undefined, ""會被轉換成false,其他都是true


Chapter 13 - 使用原始字串、數字、布林值


* 原始值在存取時,會變轉換成物件,提供該物件的屬性。完成屬性的存取後,該物件就會被捨棄,又變回原始值

* 如果要直接存取數字原始值的屬性,必須在被轉換成物件之間對數字賦值(evaluate),例如 1..toString()  (<- br="" clear="none">
  (這超不懂的,WTF)

* 避免使用new建構式產生原始值,避免typeof變成Object()


Chapter 14 - null


* null用來表示某個屬性存在,但沒有值

* 檢驗null,請用 ===
  - typeof 會是 Object()
  - ==無法區分null與undefined


Chapter 15 - undefined


* 用途一:表示一個變數尚未被賦值

* 用途二:表示一個屬性不存在(包括在繼承鍊裡也找不到)

* 不該自行把某變數賦值為undefined,因為此時你宣告了變數了,他不是不存在,只是空值,應該要給null


Chapter 16 - Math


* Math是特別的內建物件,無法用他產生instance,因為他沒有建構式

* Math內大寫開頭的常數屬性,無法改變他們的值

2010年1月3日 星期日

Long polling

之前參加Tossug辦的plurk首席開發Amir Salihefendic的講座
恩...語言真的是科技傳遞的障礙...
大概聽了個四分之一懂...

會後協同Sleepnova大的某工研院朋友,跟amir問了關於long polling的問題
他說他剛剛的投影片有錯誤,因為他是copy & pasty所以多了幾條線

Long Polling中間的response要在放下面一點點,沒有跟event對齊,並且在request上面
Comet則沒有較下面的兩條request。
(懶的重畫,自己想像吧 XD)

上面的patch是錯的,而且Amir其實已經把圖改好了,現在的公布出來的投影片內容是正確的
可參考14頁的內容

後來跟宗董在他的部落格上討論

我google了一下...
http://en.wikipedia.org/wiki/Push_technology 有對long polling的介紹...隨手亂翻譯一下:
Long polling 是一種傳統查詢(poll)技術的變形 and 允許模擬從伺服器到用戶端的資訊推送(information push)。有了long polling,客戶端從伺服器要求資訊相似於一般的查詢。但是,如果伺服器沒有任何可用的資訊給客戶端, 伺服器會保留這個需求(request)並等待一些資訊可用 instead of 送出一個空的回應。一但資訊變成available (或是在適當的timeout後), 一個完整的回應被送至客戶端。客戶端將會一般的立即重新要求資訊從伺服器,所以伺服器將幾乎總是有一個可用的等待需求而可以用來交付資料來回應事件。
Long Polling 本身不是推送技術,但是可以被使用在真正的推送還不可能的環境。
http://blog.perplexedlabs.com/2009/05/04/php-jquery-ajax-javascript-long-polling/這邊有php實作long polling的example:
看起來是就用usleep()給他等沒錯 XD

關於Long Polling保留連線的所造成負擔的問題,這裡有篇文章有解釋,我還沒仔細看http://cometdaily.com/2007/11/16/more-on-long-polling/


我也開了firegub看plurk怎麼搞,waiting time都很短沒錯(< 1sec)
可是status bar顯示的"等待comet05.plurk.com"都持續顯示好幾秒...
而且firebug網路那頁顯示的時間點怪怪的
明明是剛剛才送出的request,完成後它的bar卻是顯示從好幾秒之前開
我想可能要開個Wireshark之類的看比較準。
我覺得我認知的應該沒錯,不過plurk實際實作上可能有其他不一樣的細節吧?

2009年6月26日 星期五

Firefox extension開發心得

開發時的錯誤輸出...
有三種...

(1)使用ConsoleService
https://developer.mozilla.org/en/Console_service
這種會把錯誤訊息顯示在"工具->錯誤主控台"裡面

(2)Components.utils.reportError
https://developer.mozilla.org/en/Components.utils.reportError
這種也會顯示在錯誤主控台,但是好像主要是在try-catch的時候顯示exception物件用的

(3)window.dump
https://developer.mozilla.org/en/DOM/window.dump
顯示在終端機,似乎必須要在終端機下面執行的才會顯示
windows下就是要開個dos視窗來執行才會看到

source code trace心得...
xpcom.js
在global宣告了XPCOM
Utils
以及其基本的method跟attribute(跟XPCOM服務相關的)

chrome.js
在global宣告了FirebugChrome,因該是整個Firebug的core
另外還有一些全域的helper function

lib.js
讓FBL=XPCOMUtils
然後開始替FBL加入其他的member
大部份比較像是跟FBL內部的helper,擷取註解標示出來的區塊:
// Basics
// Localization
// Visibility
// Window iteration
// CSS classes
// DOM queries
// DOM Modification
// XPath
// Clipboard
// Graphics
// CSS
// XML Serialization
// String escaping
// Menus
// Stack Traces
// Event Monitoring
// Functions
// Source Files
// Firefox browsing
// JavaScript Parsing
// Events
// DOM Events
// URLs
// Network
// Network Tracing
// Programs
...中間有幾塊沒說明...
// DOM Constants
// Debug Logging
// Time Utils
這邊的method有些是用'函式資料'有些是用'函式實字'
差別在那呢? 或許跟closure有關?要在看看...
FBL有一個叫作namespace的陣列
後面的.js大多是用一個未命名的函式當作名稱空間
然後用FBL.ns() push到FBL.namespace裡面...
有趣的是每丟一個真正有用的namespace進去,會多丟一個空的{}區塊進去
好像是要避免全部namespace緊緊的靠在一起可能會有什麼問題...

後面的js都在global下面增加一些物件
但是好像是包在一個namespace下面,所以不會撞在一起?
到底是什麼不會撞在一起?
是namespace下面,物件之外的常數跟function?
還是物件下面的member?(物件下面的東西本來就不會撞在一起啊?)

FirebugChrome.$()會去call FBL.$()
$()是用來getElementById的

domplate.js
宣告了好幾個物件
另外也對FBL跟global加了幾個function

2008年12月27日 星期六

永和平價超值美味鐵板燒

本文轉發到
http://www.ipeen.com.tw/i/%E6%88%91%E5%90%83%E9%81%8E%E6%9C%80%E5%A5%BD%E5%90%83%E7%9A%84%E5%B9%B3%E5%83%B9%E9%90%B5%E6%9D%BF%E7%87%92/comment/comment.php?id=20362

去了

2008年11月8日 星期六

娛樂

電腦有什麼好玩的?
在好玩的遊戲遲早會膩
電影看完也不會想很快複習
沒看的也沒興致去點開資料夾
去BBS看人家吵架? 我是小孩子嘛?

裝了DOS模擬器, 把小學買的英文遊戲拿出來玩, 剛玩很感動, 一陣子又暱了
裝了PS模擬器, 把國中在電動玩具店沒全破的月下惡魔城全破, 打玩也是空虛
不過不得不承認, 那些東西, 就算在現在這個年代, 我還是很好玩
是我停留在那時代嘛? 現在的3D畫面, 做的跟真的一樣, 我完全沒玩過, 也不知道是不是真的很好玩...

記得以前英文會話, 我說我最喜歡的是成長的感覺
coding會讓我有這感覺, 因為感覺學會了, 完成了, 有成就感!
唸書得到新知識也是...

可是有時coding又是為賺錢或交作業, 唸書是為了學校

搞到最後, 怎麼覺得人生好無趣...
我需要一些值得我付出生命的東西

2008年8月4日 星期一

音樂是有錢人的玩意

//原文發於2007/8/14

這句話不知道是誰說的
其實也可以替換成很多不同的名詞:
比方:
藝術是有錢人的玩意
玩車是有錢人的玩意
出國是有錢人的玩意
把妹是有錢人的玩意...etc

不過事實上
是因為有錢家小孩做事不大需要在意未來而能夠全心全意的投入

我所看到的平平淡淡

//原文發於2007/7/6

//有些事情這邊不好說, 就都用代號吧


原來事情的主軸是A, 想說順便把之前想做的事情列為B吧!

結果突然間基於理由Ra 導致A不可行
只能做B;

於是基於Ra的理由為原則, 我設計了Ba.
但是提出後, 結果總是我少考慮了Ra+1;
於是我拿Ra+1再次考量,得到Ba+1; 但又少考慮了Ra+2
經由歸納法可得證,我求到Bn還是會沒有結果

依照現有的條件考量, 提出解決方案
但需求卻一直增加.

最後終於導出一般解的公式, 可以直接套用並推翻所有Bn(令n=1~無限大)
以上!!!得證! 命題一開始便不可能成立

離開邏輯,回到事實
對於真正困於這個問題的人來說
根本不是去觀察邏輯上的關係, 而是要知道實際的情況是如何

尊重對方,照對方的需求這些根本不是重點
對於真正處於這個問題的人來說, 解決之道在本身的實力; 行事的手腕
為什麼到最後好像是因為提不出好的方案所以作罷?

講白了!
無限的包容嘛? 無盡的支持嘛? 這些東西大家都想要
想要的原因是這樣就以為自己是自由的
真正的自由還需要別人供給這些嘛? 已經自由了還需要外援嘛

都只是在已經安排好的安穩的沒有選擇的選擇上, 給予能夠自由選擇的假象

我就是聽了假象,做了假象,所以才困於假象而不能為別人創造假象
就是偏激怎麼樣, 我是處女座的,要偏激就偏激到底, 用假象讓對方接受, 就是都可以接受的選擇了