Showing posts with label javascript. Show all posts
Showing posts with label javascript. Show all posts
March 3, 2015
支付寶即時到帳串接小記
先說個結論:要用公司的帳號透過工人智慧申請的方式去開通「即時到帳」,取得 PID 之後才能開發。開發階段沒有 sandbox 可用,要用真正的個人帳號以每次 0.01 元的消費方式來測試。當然財力雄厚的人,想要用 100 元也可以啦。
前些日子接到需求要接上支付寶的金流。在此之前我只有很爽地直接用 tka 接好的 paypal,測試的時候用一組測試卡號「盡量刷」,享受那種刷卡不用付錢的精神富裕。
這是頭一次接金流,還要用中國的支付寶。
我對支付寶的認識就是:「嗯,很大間的公司」,還要搜尋一下才能確認是馬雲的東西,我對馬雲最大的認識就是經常在 Facebook 看見他的照片及勉勵小語,好比「他媽的這根本不是我說的話」。
接完了回頭看其實也沒啥,反正阿宅就是看完文件把路打通,每個人都會。只是一些準備工作比較讓人摸不著頭緒,這邊稍微紀錄一下,給需要的人一點幫助。
我接的金流是「即時到帳」(Direct Pay),在自家的網站上以 sign 過的資料產生一個 link,user 點下 link 之後就會被導到 alipay 的網站,在 alipay 登入 user 自己的帳戶之後就會看到對應的訂單,選擇付款之後,錢就會直接從 user 的帳戶轉到自己網站的帳戶。
假設你是一位要開發這個功能的技術宅,那麼你需要準備這些東西,有這些就能安心開發了
一開始連需要什麼功能都不知道,摸索了一下確定自己需要的是即時到帳。以為在這個飛機滿天飛,一堆人早上在台北吃早餐,中午在日本吃拉麵的年代,搜尋 "alipay api" 找到的支付寶開放平台以為就能開工,其實根本用不到。
因為 paypal 刷得很開心,以為 Sandbox 可以有相同體驗,後來才知道根本不行。
支付寶上頭找不到客服的 email,也許是國情不同,他們流行用線上客服。在上班時間排隊了一個小時之後終於轉到技術客服,還要用 cconv 轉成簡體發問
「我要開發即時到帳,一定要簽約完後才能開始開發嗎」『對』
「Sandbox 能用嗎?」『那個沒用,要用帳號每次消費 0.01 測試吧』
回頭想想不管是 Sandbox 或是 API website,都寫著「支付寶開放平台」,跟我要做的東西一點關係都沒有,是我自己充滿了過份美好的想像。
如果你是用 nodejs 開發的人,收 notification 的時候可能會遇到 req 沒有 body 的情況,請參考這篇 nodejs 集成支付宝能收到 notify 请求但收不到 notify 数据,也許是平常有牽老奶奶過馬路,這篇發問與解答正好出現在我撞牆的前一天,省去了很多冤枉時間。(具體錯在哪一行 code 我現在懶得找,歡迎大德補完)(如果是日本的金流我應該就會很認真找了 >/////<)
其實也就是那一篇讓我覺得:「啊,好險他們有寫,真感謝他們 <(_ _)>」。剛剛洗澡的時候也覺得自己也要來稍微整理一下,搞不好可以幫到哪位跟我一樣沒有頭緒的人:如果你的需求跟我一樣,那你只要/必須要準備好上面的東西,才能/就能放心開工了。
後來,Ly 說是 Paypal 比較先進,不是支付寶太落後,大部分的金流都跟支付寶一樣。
唉...
前些日子接到需求要接上支付寶的金流。在此之前我只有很爽地直接用 tka 接好的 paypal,測試的時候用一組測試卡號「盡量刷」,享受那種刷卡不用付錢的精神富裕。
這是頭一次接金流,還要用中國的支付寶。
我對支付寶的認識就是:「嗯,很大間的公司」,還要搜尋一下才能確認是馬雲的東西,我對馬雲最大的認識就是經常在 Facebook 看見他的照片及勉勵小語,好比「他媽的這根本不是我說的話」。
接完了回頭看其實也沒啥,反正阿宅就是看完文件把路打通,每個人都會。只是一些準備工作比較讓人摸不著頭緒,這邊稍微紀錄一下,給需要的人一點幫助。
我接的金流是「即時到帳」(Direct Pay),在自家的網站上以 sign 過的資料產生一個 link,user 點下 link 之後就會被導到 alipay 的網站,在 alipay 登入 user 自己的帳戶之後就會看到對應的訂單,選擇付款之後,錢就會直接從 user 的帳戶轉到自己網站的帳戶。
假設你是一位要開發這個功能的技術宅,那麼你需要準備這些東西,有這些就能安心開發了
- 一個可以付款的一般帳號
- 一個可以收款,且申請了即時到帳功能的公司帳號,需要的帳戶資訊包括
- seller email:就是這個公司帳號的 email
- PID
- Key
- 技術文件,就是到 如何集成,借助第三方系統開發的網站 下載文件,裡面有 ASP/Java/PHP 的 sample code
- 用 node.js 的人,可以試 lodengo/alipay.git ,會動。因為 direct pay 只用到其中一小部份,而且它沒有血清授權,所以我後來直接重寫,避免 legal issue
一開始連需要什麼功能都不知道,摸索了一下確定自己需要的是即時到帳。以為在這個飛機滿天飛,一堆人早上在台北吃早餐,中午在日本吃拉麵的年代,搜尋 "alipay api" 找到的支付寶開放平台以為就能開工,其實根本用不到。
因為 paypal 刷得很開心,以為 Sandbox 可以有相同體驗,後來才知道根本不行。
支付寶上頭找不到客服的 email,也許是國情不同,他們流行用線上客服。在上班時間排隊了一個小時之後終於轉到技術客服,還要用 cconv 轉成簡體發問
「我要開發即時到帳,一定要簽約完後才能開始開發嗎」『對』
「Sandbox 能用嗎?」『那個沒用,要用帳號每次消費 0.01 測試吧』
回頭想想不管是 Sandbox 或是 API website,都寫著「支付寶開放平台」,跟我要做的東西一點關係都沒有,是我自己充滿了過份美好的想像。
如果你是用 nodejs 開發的人,收 notification 的時候可能會遇到 req 沒有 body 的情況,請參考這篇 nodejs 集成支付宝能收到 notify 请求但收不到 notify 数据,也許是平常有牽老奶奶過馬路,這篇發問與解答正好出現在我撞牆的前一天,省去了很多冤枉時間。(具體錯在哪一行 code 我現在懶得找,歡迎大德補完)(如果是日本的金流我應該就會很認真找了 >/////<)
其實也就是那一篇讓我覺得:「啊,好險他們有寫,真感謝他們 <(_ _)>」。剛剛洗澡的時候也覺得自己也要來稍微整理一下,搞不好可以幫到哪位跟我一樣沒有頭緒的人:如果你的需求跟我一樣,那你只要/必須要準備好上面的東西,才能/就能放心開工了。
後來,Ly 說是 Paypal 比較先進,不是支付寶太落後,大部分的金流都跟支付寶一樣。
唉...
October 8, 2013
Livescript Backcall
最近因緣際會之下開始碰 Livescript
原本好不容易把 Javascript 打通,以為可以開始用某種語言痛快說話時,突然又來了 Livescript,只好又開始牙牙學語
初碰 Livescript 總感覺到有無形的牆擋在前面,怎麼唸也不順,直到聽見高村長提到關鍵字「Perl」,心中好像有什麼結被打開了,與其把它當成某種 javascript 的變型,似乎把它當成 Perl 的變型要好一點,雖然原作者可能不這麼想 XD
心結打開就舒坦了一些
高村長又曾經開示 Livescript 重要的特色之一就是 backcall。如果沒有誤解,backcall 要解決的問題之一就是 javascript 可怕的 callback 地獄。以一段 pseudocode 來說
這段話可以如此解釋:從 http 取得一份資料,成功取得就打開檔案,然後把取得的資料存進檔案裡面。這些動作相當仰賴 callback,我們會一層又一層地將 function 物件傳進去,太多層就是 callback hell !!
用 Livescript 就可以透過 backcall 的方式這麼寫
看起來比較簡潔,先來理解 backcall 的形式
箭頭的右側就是我們最先呼叫的 function,箭頭的左側則是傳入的 callback 參數,下方是 callback 的主體。也因此右側自成一組,左側與下方自成一組,看程式碼的時候就要這麼看它
從形式上來看會是「執行 open_file 的 callback 是底下那一塊,左方是 callback 參數」。
既然要閱讀程式碼,就要能夠「唸」出來。我自己的念法就會是「http fetch data 之後就打開檔案,打開檔案之後就存入」,至於 parameters 的部份都忽略不看
update: 因為 callback chain 的關係,經常 callback 只會接受一個參數,也就是上一個 function call 的 return value。(不然就是再多一個 exception) 。在此前提下閱讀 backcall 就會簡單很多,上面的例子就是: http fetch data 的回傳值是 json,打開檔案回傳值是 filename,接著把 json 存進去 filename
這是我個人的理解方式,希望給同樣頭痛的人一點幫助
ps. 由於 backcall 底下都會是 callback body,若有不屬於 body 的 statements,用 do 就可以解決了
原本好不容易把 Javascript 打通,以為可以開始用某種語言痛快說話時,突然又來了 Livescript,只好又開始牙牙學語
初碰 Livescript 總感覺到有無形的牆擋在前面,怎麼唸也不順,直到聽見高村長提到關鍵字「Perl」,心中好像有什麼結被打開了,與其把它當成某種 javascript 的變型,似乎把它當成 Perl 的變型要好一點,雖然原作者可能不這麼想 XD
心結打開就舒坦了一些
高村長又曾經開示 Livescript 重要的特色之一就是 backcall。如果沒有誤解,backcall 要解決的問題之一就是 javascript 可怕的 callback 地獄。以一段 pseudocode 來說
http.fetch_data(function(json) {
open_file(function(filename) {
save_to_file(filename, json);
});
});
這段話可以如此解釋:從 http 取得一份資料,成功取得就打開檔案,然後把取得的資料存進檔案裡面。這些動作相當仰賴 callback,我們會一層又一層地將 function 物件傳進去,太多層就是 callback hell !!
用 Livescript 就可以透過 backcall 的方式這麼寫
json <- http.fetch_data filename <- open_file save_to_file filename, json
看起來比較簡潔,先來理解 backcall 的形式
callback_parameter <- caller_function callback_body
箭頭的右側就是我們最先呼叫的 function,箭頭的左側則是傳入的 callback 參數,下方是 callback 的主體。也因此右側自成一組,左側與下方自成一組,看程式碼的時候就要這麼看它
json <- http.fetch_data filename <- open_file save_to_file filename, json
從形式上來看會是「執行 open_file 的 callback 是底下那一塊,左方是 callback 參數」。
既然要閱讀程式碼,就要能夠「唸」出來。我自己的念法就會是「http fetch data 之後就打開檔案,打開檔案之後就存入」,至於 parameters 的部份都忽略不看
update: 因為 callback chain 的關係,經常 callback 只會接受一個參數,也就是上一個 function call 的 return value。(不然就是再多一個 exception) 。在此前提下閱讀 backcall 就會簡單很多,上面的例子就是: http fetch data 的回傳值是 json,打開檔案回傳值是 filename,接著把 json 存進去 filename
這是我個人的理解方式,希望給同樣頭痛的人一點幫助
ps. 由於 backcall 底下都會是 callback body,若有不屬於 body 的 statements,用 do 就可以解決了
do json <- http.fetch_data filename <- open_file save_to_file filename, json this_is_in_callback \yeah this_is_not_in_callback \yeah
December 27, 2012
在 Blogger 貼上程式碼
在 blogger/blogspot 想要貼程式碼並且提供比較清晰的外觀,之前找到的方法不外乎幾種
恰好最近學了一點點 js,自己動手做很簡單的 pretty code。先定義幾個 css 格式,網頁下載完成之後,透過 javascript 對於帶有 code 類別的 pre 區塊做修改。
修改的邏輯也很簡單,僅僅只是用 regular expression 找出一些定義好的字串上點顏色罷了。我也不常貼上太多程式碼,因此正規表示式沒有寫得很認真,剛好我夠用而已。
會變成
接下來找到 javascript 的區塊貼上程式碼,請注意「這一塊不能直接貼上」,這邊是看網頁原始碼的時候看到的結果。真正要貼上的是底下那一塊
因為貼上的對象是 blogger 的 template,因此要把 & 或 < 或 > 再做一次轉換,實際上真正要貼進 blogger 的 js code 是這一段(看不懂了吧!所以我才要先貼上面比較有人性的部份XD)
- 把程式碼貼到一些 formatting tool,把程式碼轉成帶有顏色的 html code 之後再貼回 blogger
- 把 javascript 檔放到另外一個 host,開啟網頁的時候載入 js 檔對 source code 做修改
恰好最近學了一點點 js,自己動手做很簡單的 pretty code。先定義幾個 css 格式,網頁下載完成之後,透過 javascript 對於帶有 code 類別的 pre 區塊做修改。
修改的邏輯也很簡單,僅僅只是用 regular expression 找出一些定義好的字串上點顏色罷了。我也不常貼上太多程式碼,因此正規表示式沒有寫得很認真,剛好我夠用而已。
使用方法
貼上程式碼的時候為 pre 加上類別 code 即可,好比<pre class="code">
int main(void) {
printf("blah\n");
}
</pre>
會變成
int main(void) {
printf("blah\n")
}
設定方法
打開 blogspot 的設計,直接編輯 html,在 css 的部份加上這一塊pre {
margin: 5px 20px;
border: 1px dashed #666;
padding: 5px;
color: #000;
background: #f8f8f8;
white-space: pre-wrap; /* css-3 */
white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
white-space: -pre-wrap; /* Opera 4-6 */
white-space: -o-pre-wrap; /* Opera 7 */
word-wrap: break-word; /* Internet Explorer 5.5+ */
}
span.control{
font-weight: bold;
color: #A00;
}
span.type {
font-weight: bold;
color: #0A0;
}
span.literal {
color: #00C;
}
span.comment {
font-weight: bold;
color: #AAA;
}
接下來找到 javascript 的區塊貼上程式碼,請注意「這一塊不能直接貼上」,這邊是看網頁原始碼的時候看到的結果。真正要貼上的是底下那一塊
onload = function () {
var elmts,
count = 0,
regLiteral = /(('.*?'|".*?"))/g, // 'foo' or "foo"
regType = /(\W|)(void|int|float|double|byte|struct)(\W)/g, // int foo
regControl = /(\W|)(for|if|fi|while|do|done|return|each)(\W)/g, // while()
regClearCmt = /(\/\*.*?)()(.*?)(<\/span>)/g,
regClearCmts = /(\/\/.*?)()(.*?)(<\/span>)/g,
regCmtsStart = /\/\*/g, //for /*
regCmtsEnd = /\*\//g, //for */
regCmt = /\/\/(.*)/g, //for //
replaceLtGt = function (pre) {
var text = pre.innerHTML;
// <a> to <a>
pre.innerHTML = text.replace(/<(.+?)>/gi, "<$1>");
},
setColor = function (pre) {
var text = pre.innerHTML;
text = text.replace(regLiteral, "$1");
text = text.replace(regType, "$1$2$3");
text = text.replace(regControl, "$1$2$3");
text = text.replace(regClearCmt, "$1$3");
text = text.replace(regClearCmts, "$1$3");
text = text.replace(regCmtsStart, "/*");
text = text.replace(regCmtsEnd, "*/");
text = text.replace(regCmt, "//$1");
pre.innerHTML = text;
};
elmts = document.querySelectorAll("pre.code"),
count = elmts && elmts.length;
while (count > 0) {
count--;
replaceLtGt(elmts[count]);
setColor(elmts[count]);
}
};
因為貼上的對象是 blogger 的 template,因此要把 & 或 < 或 > 再做一次轉換,實際上真正要貼進 blogger 的 js code 是這一段(看不懂了吧!所以我才要先貼上面比較有人性的部份XD)
onload = function () {
var elmts,
count = 0,
regLiteral = /(('.*?'|".*?"))/g, // 'foo' or "foo"
regType = /(\W|)(void|int|float|double|byte|struct)(\W)/g, // int foo
regControl = /(\W|)(for|if|fi|while|do|done|return|each)(\W)/g, // while()
regClearCmt = /(\/\*.*?)(<span class=".*?">)(.*?)(<\/span>)/g,
regClearCmts = /(\/\/.*?)(<span class=".*?">)(.*?)(<\/span>)/g,
regCmtsStart = /\/\*/g, //for /*
regCmtsEnd = /\*\//g, //for */
regCmt = /\/\/(.*)/g, //for //
replaceLtGt = function (pre) {
var text = pre.innerHTML;
// <a> to &lt;a&gt;
pre.innerHTML = text.replace(/<(.+?)>/gi, "&lt;$1&gt;");
},
setColor = function (pre) {
var text = pre.innerHTML;
text = text.replace(regLiteral, "<span class=\"literal\">$1</span>");
text = text.replace(regType, "$1<span class=\"type\">$2</span>$3");
text = text.replace(regControl, "$1<span class=\"control\">$2</span>$3");
text = text.replace(regClearCmt, "$1$3");
text = text.replace(regClearCmts, "$1$3");
text = text.replace(regCmtsStart, "<span class=\"comment\">/*");
text = text.replace(regCmtsEnd, "*/</span>");
text = text.replace(regCmt, "<span class=\"comment\">//$1</span>");
pre.innerHTML = text;
};
elmts = document.querySelectorAll("pre.code"),
count = elmts && elmts.length;
while (count > 0) {
count--;
replaceLtGt(elmts[count]);
setColor(elmts[count]);
}
};
要把「貼上 template 的醜陋內容再轉一次變成能夠貼上 blog 文章」這樣轉來轉去自己都快被搞混了,希望我沒有貼錯December 19, 2012
Javascript 的 Object 與 Function
雖然說只要翻兩下書看幾個網站就能開始寫 code,而且看了這些東西也不見得對於寫程式有一日千里的幫助。出於阿宅很純粹的好奇心,我還是花了點時間看了 ECMAScript Q___Q
程式寫了一段時間,有時會對某一句天經地義的話沉思很久,總感覺此中有真意,欲辯「不知言」 - 不知道該怎麼解釋它,當然也有可能是庸人自擾,痴人發夢。往往好奇心就在此時被挑起,追尋了半天終於得到了一個原本就知道而且跟大家一模一樣的結論。或許此時只能用「過程比結果重要」來安慰自己。
從來沒想過自己會寫 javascript,剛碰 javascript 就讀到了不少讓人「津津樂道」的特色。好比 Hoisting 或 Closure 這種沒有在 spec 裡面出現,而是在實務中衍生出來的概念,又或著惡名昭彰的全域變數,一不小心就會跟它打上交道,看到不少說法都是因為 spec 定得不好。
這就有意思了,究竟是什麼樣的 spec 可以把一個語言搞成這樣?平常會用觀察的方式去理解一個語言的行為,但是 Javascript 的「出名」讓我有點擔憂,害怕自己觀察到的是某一個實作獨有的現象。因此才會去翻 ECMAScript 順便滿足好奇心。
好奇心被挑起之後,想要釐清以下幾個問題
接下來是一點閱讀的心得與筆記,若有疏誤請不吝指教
在 Overview 的部份對一些常見且富含多種意義的名詞做了稍微明確解釋,先記起這些名詞往後會比較順利
[[Get]] 指向一個 internal method,這個 method 需要一個參數叫 propertyName,執行的結果是回傳一個 property 的 value。
而 [[Prototype]] 就是 __proto__,至於它的值後面再說明。
此外,某些物件還有這些 internal properties
接下來更深入地看一下產生 Function object 的過程
產生 Function object 的時候,也會並為該物件設定一些 properties。好比把 [[Call]], [[Constructor]] [[Code]]。Code 的內容是 FunctionBody,[[Call]] 跟 [[Constructor]] 指向 internal method。
執行這個 function 的時候(call function),就會 invoke [[Call]],[[Call]] 指向了 built-in function,作用是拿 [[Code]] 的值來執行。
如果用 new 來執行 function,就會 invoke [[Constructor]]。spec 說 [[Constructor]] 也會去 inkvoke [[Call]],但是多了一些動作,譬如說設定 prototype,而且在 invocke [[Call]] 的時候會把 'this' 指到一開始產生的物件。
所以 new 跟平常的 function call 各自執行不同的 internal method,前者會多做一些事情,譬如說把 this 指向剛剛產生的物件,以及設定 prototype。
prototype property 跟 [[Prototype]] 是不一樣的東西。*.prototype 僅是一個 property,它什麼都可以指。而 [[Prototype]] 是 internal property,會指向 Constructor 的 prototype property,或是內建物件的 prototype property,總之就是會指向某一個物件,查找 property 的時候才有一個 chain 可以用。謹記這兩者的分別,閱讀 jQuery core 的時候會有幫助。
程式寫了一段時間,有時會對某一句天經地義的話沉思很久,總感覺此中有真意,欲辯「不知言」 - 不知道該怎麼解釋它,當然也有可能是庸人自擾,痴人發夢。往往好奇心就在此時被挑起,追尋了半天終於得到了一個原本就知道而且跟大家一模一樣的結論。或許此時只能用「過程比結果重要」來安慰自己。
從來沒想過自己會寫 javascript,剛碰 javascript 就讀到了不少讓人「津津樂道」的特色。好比 Hoisting 或 Closure 這種沒有在 spec 裡面出現,而是在實務中衍生出來的概念,又或著惡名昭彰的全域變數,一不小心就會跟它打上交道,看到不少說法都是因為 spec 定得不好。
這就有意思了,究竟是什麼樣的 spec 可以把一個語言搞成這樣?平常會用觀察的方式去理解一個語言的行為,但是 Javascript 的「出名」讓我有點擔憂,害怕自己觀察到的是某一個實作獨有的現象。因此才會去翻 ECMAScript 順便滿足好奇心。
好奇心被挑起之後,想要釐清以下幾個問題
- 什麼叫做物件
- 什麼叫做 function
- 什麼是 function call, new,constructor
- 產生新物件的過程為何
- 產生的新物件與 constructor 的關係為何
接下來是一點閱讀的心得與筆記,若有疏誤請不吝指教
4.2 Language Overview
4.2 指的是 spec 裡面的 4.2 章節,後面還會重複出現類似的數字。
在 Overview 的部份對一些常見且富含多種意義的名詞做了稍微明確解釋,先記起這些名詞往後會比較順利
- ECMAScript program
一群可以相互溝通的物件(is a cluster of communicating objects),程式就是在物件的互動之中完成功能。 - ECMAScript object 帶有一些 properties 的集合。(is a collection of properties each with zero or more attributes that determine how each property can be used)
- Properties
容器,可保有物件、函式或是 primitive value(are containers that hold other objects, primitive values, or functions.) - Primitive value
- Undefined
- Null
- Boolean
- Number
- String
- Object
內建型別 Object 的成員(is a member of the remaining built-in type Object)
- Function 可以呼叫的 object (is a callable object.)
- Method
物件的 property 如果是個 function,稱之為 method(A function that is associated with an object via a property.)
- Object object
- Function object
- Array object
- String object
- Boolean object
- Number object
- Math object
- Date object
- RegExp object
- JSON object
- Error object
- Error
- EvalError
- RangeError
- ReferenceError
- SyntaxError
- TypeError
- URIError
8.6.2 Object Internal Properties and Methods
這一章節指出,所有的物件都一定帶有某些 internal properties,這邊僅列出幾項- [[Prototype]]
- [[Class]]
- [[Get]]
- [[GetOwnProperties]]
[[Get]] 指向一個 internal method,這個 method 需要一個參數叫 propertyName,執行的結果是回傳一個 property 的 value。
而 [[Prototype]] 就是 __proto__,至於它的值後面再說明。
此外,某些物件還有這些 internal properties
- [[Constructor]] new operator 會用這個 property
- [[Call]] 單純的 function call 會使用這個 property
- [[Code]] 只有 Function Object 會有這個屬性
接下來更深入地看一下產生 Function object 的過程
13.2 Creating Function Object
先定義名詞- FormalParameterList - 參數 list
- FunctionBody - function 的內容
- 產生 native ECMASCript object, 令其名為 F
- 除了 [[Get]] 之外設定所有的 internal methods
- 把 F 的 internal property [[Class]] 設成 "Function"
- 把 F 的 internal property [[Prototype]] 設成 Function.prototype,即 built-in object Function 的prototype 屬性所指向的物件
- 把 [[Code]] 設成 FunctionBody
- 設定許多 internal properties,其中一些 property 會指向特定的 internal method,以下這兩個與 function 的行為有關
- internal method [[Call]] 被 invoke 時這一次執行的狀態放入 funcCtx。[[Code]] 這個 internal property 就是 FunctionBody,執行之後的結果回傳,且把之前的執行狀態 restore 回來。
- internal method [[Constructor]] 被 invoke 時
- 產生新的 ECMAScript object(假設叫 obj),並且設定一些 internal methods。
- 把 obj 的 [[Class]] 設成 "Object"
- 對 F 呼叫 [[Get]] property,參數是 "prototype",假設呼叫的結果叫做 proto
- 如果 proto 是一個 Object,把 obj 的 [[Prototype]] 指向該物件
- 如果 proto 不是一個 Object,把 obj 的 [[Prototype]] 指向 built-in Object 的 prototype 屬性
- 回傳值是 invoke [[Call]] 的結果並且把 this 指向新產生的 Obj 。因為 [[Call]] 其實是執行 Code,所以Constructor 與 Call 都同樣是去跑一遍 Code
Function 也是物件,只是這個物件帶的屬性有點不一樣,因此成為一個可以呼叫(callable)的物件。
產生 Function object 的時候,也會並為該物件設定一些 properties。好比把 [[Call]], [[Constructor]] [[Code]]。Code 的內容是 FunctionBody,[[Call]] 跟 [[Constructor]] 指向 internal method。
執行這個 function 的時候(call function),就會 invoke [[Call]],[[Call]] 指向了 built-in function,作用是拿 [[Code]] 的值來執行。
如果用 new 來執行 function,就會 invoke [[Constructor]]。spec 說 [[Constructor]] 也會去 inkvoke [[Call]],但是多了一些動作,譬如說設定 prototype,而且在 invocke [[Call]] 的時候會把 'this' 指到一開始產生的物件。
所以 new 跟平常的 function call 各自執行不同的 internal method,前者會多做一些事情,譬如說把 this 指向剛剛產生的物件,以及設定 prototype。
prototype property 跟 [[Prototype]] 是不一樣的東西。*.prototype 僅是一個 property,它什麼都可以指。而 [[Prototype]] 是 internal property,會指向 Constructor 的 prototype property,或是內建物件的 prototype property,總之就是會指向某一個物件,查找 property 的時候才有一個 chain 可以用。謹記這兩者的分別,閱讀 jQuery core 的時候會有幫助。
Subscribe to:
Posts (Atom)

