Lp trình hng đi tng trong Javascript và các kiu mu thit k
Ngô Quang Trung – email: / www.phonegap.vn/forum 1
MC LC
LI NÓI U 6
I.Hàm function 7
1.1.Kin thc nn v hàm function 7
1.1.1.Cách ti thiu hóa s bin toàn cc 8
1.2.nh ngha thut ng 13
1.3.So sánh gia vic khai báo vi biu thc : tên names và s leo thang hoisting 15
1.4.Thuc tính name ca hàm function 16
1.5.S leo thanh ca hàm function - Function Hoisting 17
1.6.Kiu mu callback 19
1.6.1.Mt ví d mu v callback 19
1.6.2.Hàm callback và phm vi tn ti ca bin trong hàm callback 22
1.6.3.Lng nghe s kin không đng b 24
1.6.4. tr Timeouts 25
1.6.5.Hàm callbacks trong các th vin 25
1.6.6.Cách tr v trong hàm functions 25
1.6.7.Các hàm functions t đnh ngha 27
1.6.8.Các hàm functions tc thi 29
1.6.8.1.Các tham s ca 1 hàm tc thi 30
1.6.8.2.Các giá tr đc tr v t các hàm tc thi 31
1.6.8.3.Cách s dng và u đim 33
1.6.9.Cách khi to các đi tng tc thi 34
1.6.10.Phân nhánh thi gian khi to - Init-Time Branching 35
1.6.11.Các thuc tính ca functions – kiu mu ti u hóa b nh Memoization Pattern 37
1.6.12.Các đi tng cu hình - Configuration Objects 39
1.6.13.Curry 41
1.6.14.Function Application 41
1.6.15.Partial Application 42
1.6.16.Currying 44
1.6.17.khi nào ta s dng Currying 47
II.T mng arrays cho ti các đi tng objects 48
2.1.Các phn t, các thuc tính, các phng thc 50
Lp trình hng đi tng trong Javascript và các kiu mu thit k
Ngô Quang Trung – email: / www.phonegap.vn/forum 2
2.2.Các mng arrays kt hp 50
2.3.Các truy cp vào các thuc tính ca đi tng 51
2.4.Cách gi các phng thc ca 1 đi tng 53
2.5.Cách bin đi các thuc tính / phng thc 54
2.6.Các s dng t khóa this 55
2.7.Các hàm to constructor 55
2.8.i tng toàn cc Global Object 57
2.9.Thuc tính to 58
2.10.Toán t instanceof 59
2.11.Các hàm functions mà tr v các đi tng objects 59
2.12.Các chuyn tip các đi tng 61
2.13.Cách so sánh các đi tng objects 62
III.Các đi tng đc xây dng sn 63
3.1.i tng object 63
3.2.i tng Mng array 64
3.3.i tng Function 67
3.3.1.Các thuc tính ca đi tng function 68
3.3.2.Các phng thc trong các đi tng objects function 71
IV.Biu thc chính quy 74
4.1.Các thuc tính ca các đi tng Objects 74
4.2.Các phng thc ca các đi tng regexp 76
4.3.Các phng thc string mà nhn các biu thc chính quy nh các tham s 76
4.3.1.search() và match() 77
4.3.2.replace() 77
4.3.3.Các hàm Replace callbacks 78
4.3.4.split() 80
4.3.5.Cách chuyn tip 1 chui string khi 1 regexp đc nh kì vng 80
4.4.Quy tc mu trong biu thc quan h 81
V.Prototype 88
5.1.Thuc tính prototype 88
5.2.Cách thêm các phng thc và thuc tính bng cách s dng Prototype 88
5.3.Cách s dng các thuc tính và phng thc ca Prototype 90
5.4.Các thuc tính chính gc so vi các thuc tính đc thêm vào qua prototype 91
Lp trình hng đi tng trong Javascript và các kiu mu thit k
Ngô Quang Trung – email: / www.phonegap.vn/forum 3
5.5.Ghi đè thuc tính ca prototype vi thuc tính chính gc 93
5.6.Các lit kê các thuc tính 94
5.7.isPrototypeOf() 97
5.8.Bí mt v __proto__ Link 98
5.9.Cách làm gia tng các đi tng đc xây dng sn 100
5.10.Mt vài ghi chú v Prototype 101
VI.S k tha 106
6.1.Các chui móc ni prototype 106
6.2.Ví d v chui móc ni prototype 107
6.3.Cách chuyn các thuc tính đc chia s vào bên trong prototype 111
6.4.Cách tha k ch t prototype 113
6.5.Hàm to Constructor tm thi - new F() 115
6.6.Uber – truy cp đi tng cha t đi tng con 117
6.7.Cách phân tách phn k tha vào trong 1 hàm function 119
VII.Các kiu mu to đi tng object 120
7.1.Các phng thc và thuc tính riêng t 120
7.1.2.Các thành viên riêng t 120
7.1.3.Các phng thc đc u tiên 121
7.1.4.Các thiu sót quyn riêng t 122
7.1.5.Object Literals và quyn riêng t 123
7.1.6.Các Prototypes v quyn riêng t 125
7.1.7.Cách phát hin các hàm riêng nh các phng thc public 126
7.2.Cách thành viên c đnh static 127
7.2.1.Các thanh viên Public Static 128
7.2.2.Các thành viên Private Static 130
7.3.Các hng s đi tng 133
7.4.Kiu mu chui hóa - Chaining Pattern 135
7.4.1.u đim và nhc đim ca kiu mu chui hóa - Chaining Pattern 136
7.5.Phng thc method() 137
VIII.Các kiu mu có kh nng tái s dng - Code Reuse Patterns 139
8.1.Kiu mu hng class so vi các kiu mu phân cp hin đi 139
8.2.Kt qu nh mong mun khi s dng s k tha theo hng classical 140
8.3.Vic k tip chui prototype 141
Lp trình hng đi tng trong Javascript và các kiu mu thit k
Ngô Quang Trung – email: / www.phonegap.vn/forum 4
8.4.Nhc đim khi s dng kiu mu #1 144
8.5.Kiu mu Classical Pattern #2 - Rent-a-Constructor – kiu mu vay mn hàm to . 145
8.5.1.Chui prototype 147
8.5.2.S đa k tha bng các hàm to vay mn 148
8.5.3.u đim và nhc đim ca kiu mu hàm khi to vay mn 149
8.6.Kiu mu Classical Pattern #3 - Rent and Set Prototype – kiu mu vay mn và thit
lp prototype 149
8.7.Kiu mu Classical Pattern #4 – chia s prototype 151
8.8.Kiu mu Classical Pattern #5 – 1 hàm to tm thi 152
8.8.1.Cách lu tr Superclass 154
8.8.2.Cách cài đt li con tr hàm khi to 154
8.9.Klass 156
8.10.S k tha hng Prototypal 159
8.10.1.Tho lun 160
8.10.2.Vic b sung ECMAScript 5 162
8.10.3.S k tha bng cách sao chép các thuc tính 162
8.10.4.Mix-ins 165
8.10.5.Vay mn các phng thc Methods 166
8.10.6.Ví d : vay mn t 1 mng array 167
8.10.7.Vay mn và ràng buc 168
8.10.8.Function.prototype.bind() 170
IX.Kiu mu thit k 172
9.1.Singleton – kiu mu duy nht 172
9.1.1.Cách s dng new 173
9.1.2.Thc th trong 1 thuc tính static 174
9.1.3.Thc th trong 1 bao đóng 174
9.2.Factory – kiu mu sn xut đi tng 178
9.2.1.i tng Object Factory đc xây dng sn 181
9.3.Iterator – kiu mu bin lp 182
9.4.Façade 185
9.5.Proxy 188
9.5.1.Mt ví d mu 190
9.6.Composite 199
9.6.1.Vn đ đt ra 199
Lp trình hng đi tng trong Javascript và các kiu mu thit k
Ngô Quang Trung – email: / www.phonegap.vn/forum 5
9.6.2.Cu trúc ca kiu mu composite pattern 202
9.6.3.Các mu ví d v kiu mu Composite Pattern 203
9.6.4.Mu ví d trong JS s dng kiu mu Composite Pattern 203
9.6.5.u đim và nhc đim ca kiu mu Composite Pattern 208
9.7.Observer – ngi quan sát 210
9.7.1.Mu ví d #1: vic đt mua tp chí 211
X.Asynchronous patterns - Kiu mu không đng b 216
10.1.Li ích và thách thc vi lp trình không đng b 216
10.2.Promises 218
10.3.Khám phá Promises trong b công c JQuery 222
XI.ASYNCH JS : sc mnh ca đi tng $.DEFERRED 225
11.1.Các hàm APIS không đng b ca trình duyt 225
11.2.Cách to các ng dng 1 cách không đng b 227
11.3.Cách hiu chnh s tht bi 228
11.4.$.DEFERRED 228
11.5.Các trng hp mu 232
11.6.JQuery.Deferred và Promise 233
11.6.1.$.Deferred 234
11.6.2.Phng thc deferred.resolve() 235
11.6.3.Phng thc deferred.reject() 235
11.6.4.Phng thc Promise() 236
Lp trình hng đi tng trong Javascript và các kiu mu thit k
Ngô Quang Trung – email: / www.phonegap.vn/forum 6
LI NÓI U
Tài liu đc vit ging nh 1 bn ghi chép, ghi li nhng th mà mình đư đc đc t các
ebook ting anh, do vy b cc sp xp ca nó có th cha chính xác, cách trình bày không
theo chun 1 ebook nào c và nhiu ch vit cha rõ ngha và không mch lc do hn ch v
ngoi ng ca bn thân mình. Tài liu mang đm tính cht cá nhân do vy bn s bt gp
trong tài liu này nhiu đon kí t in đm, in màu, c ch ln bt thng và đc tô màu
khác nhau - đó là các đon có liên quan đn nhau hay là nhng ghi chú quan trng mà bn
cn phi đc k.
Ni dung trong tài liu này đc da trên các cun ebook: “JavaScript Patterns - Stoyan
Stefanov”, “Object-Oriented JavaScript - Stoyan Stefanov”, “JavaScript: The Good Parts
- Douglas Crockford”, và 1 s bài vit ca các tác gi mà mình không còn nh rõ na.
Trc khi đc tài liu này, bn phi xác đnh mình nm rõ nhng gì thuc v c bn nht ca
Javascript nh các cách khai báo, các kiu d liu c bn, các phép toán s hc, các mnh đ
điu kin, ầ(nu bn có kin thc v 1 ngôn ng lp trình c bn nào đó, thì bn s làm quen
vi nhng gì tài liu này b qua trong Javascript 1 cách rt nhanh chóng). Tài liu này ch
tp trung vào nhng gì đc coi là đc bit nht ca Javascript so vi các ngôn ng lp trình
thông dng khác, không phi dành cho nhng ngi mi bt đu hc Javascript. 1 đim na
bn cn lu ý là trong tài liu này lc b phn tng tác gia Javascript vi DOM &
Browser bi vì bn thân mình dùng Jquery đ thay th.
Nu bn s dng Javascript kt hp vi Phonegap đ to ra các ng dng cho các nn tng
mobile, thì các tài liu sau có th bn s quan tâm ti :
“Phonegap cho ngi mi hc”:
“Cách ti u hóa môi trng lp trình ng dng cho Android”:
/>cho-android-tng-tc-my-o-android
Hoc đn gin truy cp vào th mc chia s sau:
Lp trình hng đi tng trong Javascript và các kiu mu thit k
Ngô Quang Trung – email: / www.phonegap.vn/forum 7
I.Hàm function
1.1.Kin thc nn v hàm function
Có 2 tính nng chính ca hàm functions trong JS làm cho chúng tr nên đc bit.điu đu tiên
là hàm functions cng ging nh các đi tng class objects và điu th 2 là chúng cung cp
1 phm vi tn ti ca các bin
Các hàm functions là các đi tng objects mà :
Có th to ra 1 cách linh hot trong thi gian chy trong xut quá trình thc thi ca
chng trình
Có th gán vào các bin và có th tham chiu đ sao chép giá tr sang các bin khác,
có th tham s hóa và trong 1 s trng hp nó có th b xóa
Có th chuyn tip nh các tham s vào trong hàm functions khác và cng có th
đc tr v bi hàm functions khác
Có th có thuc tính và các phng thc bên trong
Do vy có th xy ra trng hp 1 hàm function A – là 1 đi tng object, đi tng này
cha các thuc tính và phng thc – 1 hàm B khác, hàm B nhn 1 hàm C là tham s và khi
thc thi nó có th tr v hàm D.
Thông thng khi ta ngh v 1 hàm function trong JS thì ta ngha v 1 đi tng object vi
tính nng đc bit duy nht là đi tng object này có kh nng gi đc, điu này có ngha
là nó có th đc thc thi x lý
Thc t thì hàm function là đi tng object và hin nhiên ta s thy hàm to new Function()
nh sau :
// antipattern
// for demo purposes only
var add = new Function('a, b', 'return a + b');
add(1, 2); // returns 3
đon code này thì không có s ng vc gì v vic add() là 1 đi tng object. cách s dng
hàm to Function() constructor không phi là cách s dng hay vì nó s gây ra 1 vài bt tin
cho vic vit và đc hiu
Lp trình hng đi tng trong Javascript và các kiu mu thit k
Ngô Quang Trung – email: / www.phonegap.vn/forum 8
tính nng quan trng th 2 là các hàm function cung cp 1 phm vi tn ti.bt c bin nào
đc đnh ngha vi var bên trong 1 hàm function thì là 1 bin đa phng và nó không tn
ti đc bên ngoài hàm function này.vic nói rng du ngoc {} không cung cp phm vi đa
phng có ngha là nu ta đnh ngha 1 bin vi var bên trong 1 mnh đ if hay bên trong 1
mnh đ for hay mnh đ while thì điu này không có ngha là bin này là đa phng vi if
hay for.nó ch là đa phng đi vi hàm function bao quanh nó và nu không có hàm
function nào bao quanh nó thì nó là 1 bin toàn cc.nh đư nói đn chng trc thì vic
ti thiu hóa s bin toàn cc là 1 s thích tt bi vì các hàm functions là bt buc đ gi
các bin tn ti trong 1 phm vi có kim soát
1.1.1.Cách ti thiu hóa s bin toàn cc
Js s dng các hàm functions đ kim soát phm vi tn ti ca bin.1 bin đc khai báo
trong 1 hàm function là bin đa phng và nó không tn ti ngoài hàm function này.theo
cách khác, các bin toàn cc là các bin đc khai báo không trong bt c hàm functions
nào
Mi môi trng trong JS đu là 1 đi tng toàn cc global object có th đc truy cp khi ta
s dng this bên ngoài bt c hàm functions nào.mi bin toàn cc mà ta to ra tr thành 1
thuc tính ca đi tng toàn cc.di đây là 1 đon mư code nh ch ra cách to và truy cp
1 bin toàn cc trong môi trng trình duyt :
myglobal = "hello"; // antipattern
console.log(myglobal); // "hello"
console.log(window.myglobal); // "hello"
console.log(window["myglobal"]); // "hello"
console.log(this.myglobal); // "hello"
1.1.1.2.Các vn đ ny sinh vi các bin toàn cc
các vn đ ny sinh vi bin toàn cc là vic chúng đc chia s trong phm vi toàn b mư
code trong ng dng JS.chúng sng trong cùng 1 namespace toàn cc và s luôn luôn có 1
tình hung xy ra va chm trong cách đt tên – khi 2 phn tách riêng ca 1 ng dng đnh
ngha các bin toàn cc vi cùng 1 tên nhng có mc đích s dng khác nhau
đây cng là vn đ thng xy ra cho các web pages nhúng mư code không đc vit bi nhà
lp trình ca trang page đó ví d :
Lp trình hng đi tng trong Javascript và các kiu mu thit k
Ngô Quang Trung – email: / www.phonegap.vn/forum 9
1 th vin JS ca bên th 3
Các mư Scripts t 1 đi tác qung cáo
Mư code t 1 mư phân tích và lu vt ca ngi s dng bên th 3
Các loi widgets, badges, và buttons khác nhau
Chúng ta nói rng 1 trong các mư scripts ca bên th 3 đnh ngha 1 bin toàn cc đc gi ví
d nh result.sau đó bên trong 1 trong các hàm functions ca ta đnh ngha 1 bin toàn cc
khác đc gi là result.kt qu ca điu này là bin result khai báo cui cùng s ghi đè lên
bin result trc đó và mư script ca bên th 3 rt có th không hot đng
Do vy điu quan trng đ làm 1 ngi hàng xóm thân thin vi các mư scripts khác là các
chin thut ti thiu hóa s bin toàn cc
Khá là ngc nhiên là rt d dàng to ra bin toàn cc 1 cách rt vô tình trong JS bi vì 2 tính
nng ca JS.điu đu tiên là ta s dng các bin mà không khai báo chúng.và điu th 2 là JS
luôn có ng ý là toàn cc vi bt kì bin nào mà ta không khai báo thì nó s tr thành 1 thuc
tính ca đi tng toàn cc global object.xét ví d sau :
function sum(x, y) {
// antipattern: implied global
result = x + y;
return result;
}
Trong mư code trên thì result đc s dng mà không khai báo.đon code vn hot đng tt
nhng sau khi hàm function này ta kt thúc vi 1 bin toàn cc result thì đây có th là ngun
gc ca nhiu vn đ
Theo kinh nghim thì luôn luôn khai báo các bin vi var, và ta sa li ví d trc nh sau :
function sum(x, y) {
var result = x + y;
return result;
}
Lp trình hng đi tng trong Javascript và các kiu mu thit k
Ngô Quang Trung – email: / www.phonegap.vn/forum 10
1 trong nhng li d dàng to ra các bin theo hng toàn cc khác chính là chui gán liên
tip các bin var.xét đon ví d sau, thì bin a là đa phng nhng bin b là toàn cc :
// antipattern, do not use
function foo() {
var a = b = 0;
//
}
Nu ta ngn nhiên là ti sao li nh vy thì đó là bi vì s đánh giá đi t phi sang trái.đu
tiên biu thc b = 0 đc đánh giá trc và ti đây thì b không đc khai báo.giá tr tr v
ca biu thc này là 0 và nó đc gán vào 1 bin đa phng mi đc khai báo vi var
a.theo cách khác ta có th vit li nh sau :
var a = (b = 0);
nu ta đư khai báo tt c các bin và thc hin chui gán thì đây là cách tt và ta không to ra
các bin toàn cc 1 cách vô tình na :
function foo() {
var a, b;
//
a = b = 0; // both local
}
1.1.1.3.Các hiu ng ph khi ta quên var
ây là 1 đim hi khác bit gia các bin ng ý toàn cc và s đnh ngha hoàn toàn là 1 bin
toàn cc – s khác bit là kh nng không xác đnh đc các bin này bng cách s dng
toán t delete :
Các bin toàn cc đc to ra vi var ( các bin đc to ra bên ngoài bt c hàm
functions nào ) có th không b xóa
Các bin ng ý toàn cc không đc to ra vi var ( bt chp nu nó đc to ra bên
trong hàm function ) có th xóa
Lp trình hng đi tng trong Javascript và các kiu mu thit k
Ngô Quang Trung – email: / www.phonegap.vn/forum 11
iu này ch ra rng các bin toàn cc nói theo cách k thut không phi là các bin tht s
nhng chúng là các thuc tính ca đi tng toàn cc global object.các thuc tính có th b
xóa bi toán t delete trái li cng có bin không th b xóa :
// define three globals
var global_var = 1;
global_novar = 2; // antipattern
(function () {
global_fromfunc = 3; // antipattern
}());
// attempt to delete
delete global_var; // false
delete global_novar; // true
delete global_fromfunc; // true
// test the deletion
typeof global_var; // "number"
typeof global_novar; // "undefined"
typeof global_fromfunc; // "undefined"
trong ch đ nghiêm ngt ca ES5 thì vic gán các bin cha đc khai báo ( ging nh 2
bin antipatterns đon mư trên ) s vng ra 1 li
1.1.1.4.Cách truy cp đi tng toàn cc
trong các trình duyt, đi tng toàn cc có th truy cp t bt c phn nào ca đon code
thông qua thuc tính window.nu ta cn truy cp bin toàn cc mà không gõ mư cng xác
đnh vi window thì ta có th làm nh sau t bt c cp nào ca các phm vi function lng
nhau :
var global = (function () {
return this;
}());
Lp trình hng đi tng trong Javascript và các kiu mu thit k
Ngô Quang Trung – email: / www.phonegap.vn/forum 12
Cách này ta có th luôn luôn ly v đi tng toàn cc bi vì bên trong các hàm functions thì
this luôn luôn ch ti 1 đi tng toàn cc.điu này thc s không còn trong ch đ nghiêm
ngt ca ECMAScript 5, vì vy ta phi chp nhn 1 kiu mu khác khi mư code ca ta trong
ch đ nghiêm ngt.ví d nu ta đang phát trin 1 th vin thì ta có th đóng gói mư th vin
vào ngay 1 hàm function ( nh s nói chng 4 ) và sau đó t phm vi toàn cc, thì chuyn
tip vào 1 tham chiu ti this nh 1 tham s trong hàm function
1.1.1.5.Kiu mu s dng var
Bng cách s dng cu trúc var đu các hàm functions là 1 kiu mu rt hu dng và đc
chp nhn.nó có nhng u đim sau :
Cung cp 1 đa đim cho vic xem xét toàn b các bin đa phng cn có ca
function
Ngn chn các li v logic khi 1 bin đc s dng trc khi nó đc đnh ngha
Giúp ta nh đư khai báo các bin nào và do đó ti thiu hóa các bin toàn cc
Phi gõ ít mư code hn
1 kiu mu vi var nhìn nh sau :
function func() {
var a = 1,
b = 2,
sum = a + b,
myobject = {},
i,
j;
// function body
}
Ta s dng 1 cu trúc var và khai báo nhiu bin đc phân tách bi du phy.nó là 1 cách
thc hành tt.điu này có th ngn chc các li v logic và cng khin đon mư code d đc
hn.ta cng có th làm điu tng t vi DOM :
function updateElement() {
var el = document.getElementById("result"),
Lp trình hng đi tng trong Javascript và các kiu mu thit k
Ngô Quang Trung – email: / www.phonegap.vn/forum 13
style = el.style;
// do something with el and style
}
1.1.1.6.S leo thang : 1 vn đ vi các bin phân tán
JS cho phép ta có nhiu cu trúc var bt c đâu trong hàm function và tt c chúng đu
ging vi các bin đc khai báo trên đu hàm function.trng thái x lý này đc gi là s
leo thang hoisting.điu này có th hng ti các li v logic khi ta s dng 1 bin và sau đó
gán nó ln na trong hàm function.vi JS thì min là 1 bin nm trong cùng 1 phm vi (
cùng trong 1 hàm function ) thì nó đc coi là đư khai báo và ngay khi nó đc s dng trc
khi khai báo var, ví d nh sau :
// antipattern
myname = "global"; // global variable
function func() {
alert(myname); // "undefined"
var myname = "local";
alert(myname); // "local"
}
func();
1.2.nh ngha thut ng
ta xét đon mư code sau :
// named function expression
var add = function add(a, b) {
return a + b;
};
Don mư code này ch ra 1 hàm function bng cách s dng biu thc đt tên hàm named
function expression.
S khai báo này dù xy ra trc
hay sau thì nó cng xóa đi s khai
báo toàn cc trc đó – leo thang
cn tr li s khai báo toàn cc
Lp trình hng đi tng trong Javascript và các kiu mu thit k
Ngô Quang Trung – email: / www.phonegap.vn/forum 14
Nu ta b qua tên ( tên hàm chính là add ) trong biu thc trên thì ta s có 1 biu thc
hàm vô danh unnamed function expression hay đn gin đc gi là function expression hay
thông dung nht là anonymous function.nh ví d sau :
// function expression, a.k.a. anonymous function
var add = function (a, b) {
return a + b;
};
Khi ta b qua tên ca hàm function là add thì chính là ta đang s dng biu thc unnamed
function expression, điu này không gây nh hng gi ti đnh ngha và s gi ra ca hàm
function.ch có 1 s khác bit là thuc tính name ca đi tng function object s là 1 chui
rng.thuc tính name này là 1 phn m rng ca ngôn ng ( nó không phi là 1 phn trong
chun ECMA ) nhng nó li sn sàng có trong nhiu môi trng.nu ta gi li tên hàm là add
thì thuc tính add.name s cha chui add.và thuc tính name rt hu dng khi s dng 1
công c debug ging nh Firebug hay khi ta gi cùng 1 hàm function 1 cách đ quy ngay
trong thân ca nó hay theo mt khác ta cng có th b qua nó
Cui cùng, ta có các khai báo hàm.nó cng ging nh cách khai báo hàm function trong
nhng ngôn ng khác :
function foo() {
// function body goes here
}
Trong các điu l v ng pháp thì biu thc named function expressions và function
declarations là tng t nhau.v bn cht nu ta không gán kt qu ca biu thc function
expression là 1 bin, thnh thong cng không tìm ra s khác nhau gia 1 khai báo hàm
function declaration và 1 biu thc function expression
Có s khác nhau gia 2 cái là du chm phy.du chm phy là không cn thit trong khai
báo hàm function declarations nhng nó li là bt buc trong biu thc function expressions
và ta nên luôn luôn s dng nó mc dù c ch t đin du chm phy có th t làm cho ta
Lp trình hng đi tng trong Javascript và các kiu mu thit k
Ngô Quang Trung – email: / www.phonegap.vn/forum 15
1.3.So sánh gia vic khai báo vi biu thc : tên names và s leo thang
hoisting
Vy ta nên s dng khai báo hàm function declarations hay s dng biu thc hàm function
expressions?
Trong nhiu trng hp theo cú pháp thì ta không th s dng 1 khai báo.ví d nhúng
chuyn tip 1 đi tng function object ging nh 1 tham s hay đnh ngha các phng thc
trong chui miêu t đi tng :
// this is a function expression,
// pased as an argument to the function `callMe`
callMe(function () {
// I am an unnamed function expression
// also known as an anonymous function
});
// this is a named function expression
callMe(function me() {
// I am a named function expression
// and my name is "me"
});
// another function expression
var myobject = {
say: function () {
// I am a function expression
}
};
Lp trình hng đi tng trong Javascript và các kiu mu thit k
Ngô Quang Trung – email: / www.phonegap.vn/forum 16
S khai báo hàm Function declarations ch có th xut hin trong các mư hng th tc, điu
này có ngha là bên trong thân ca các hàm functions khác hay nó phm vi toàn cc.đnh
ngha ca chúng có th không đc gán vào trong các bin hay các thuc tính hay xut hin
trong li gi hàm nh là tham s.đây là 1 ví d cho phép dùng các đnh ngha hàm Function
declarations vi tt c các hàm foo(), bar(), và local() đu đc đnh ngha s dng kiu mu
khai báo function declaration pattern:
// global scope
function foo() {}
function local() {
// local scope
function bar() {}
return bar;
}
1.4.Thuc tính name ca hàm function
Nhng th khác dùng đ xét đn khi ta chn 1 đnh ngha hàm function ch là có s xut hin
ca thuc tính ch có th đc name ca hàm function hay không.nhc li 1 ln na, thuc tính
này không phi là tiêu chun nhng nó li có trong rt nhiu môi trng.trong các đnh ngha
hàm function declarations và biu thc named function expressions thì thuc tính name đc
đnh ngha.trong biu thc anonymous function expressions thì nó ph thuc vào cách thc
thi; nó có th không đc đnh ngha undefined (IE) hoc đc đnh ngha vi 1 chui rng
empty string (Firefox,WebKit):
function foo() {} // declaration
var bar = function () {}; // expression
var baz = function baz() {}; // named expression
foo.name; // "foo"
bar.name; // ""
baz.name; // "baz"
thuc tính name là rt hu dng trong công c debug nh firebug.khi debugger cn hin th
cho ta thy 1 li trong 1 hàm function thì nó kim tra s có mt ca thuc tính name và s
Lp trình hng đi tng trong Javascript và các kiu mu thit k
Ngô Quang Trung – email: / www.phonegap.vn/forum 17
dng nó nh là 1 vt đánh du.thuc tính name cng có th đc s dng đ gi ti cùng hàm
function 1 cách đ quy t trong chính thân ca nó.nu ta không thy thú v trong 2 trng
hp trên thì biu thc anonymous function expressions s tr nên d dàng hn và ít dài
dòng hn
lí do mà ta thích biu thc function expressions là vì biu thc này làm ni bt các hàm
functions cng là các đi tng objects và không có s khi to đc bit nào
chú ý : theo 1 cách k thut thì ta có th s dng 1 biu thc named function expression
và gán nó vào trong 1 bin có tên khác vi tên ca hàm function nh sau :
var foo = function bar() {};
tuy nhiên, cách thc thc thi này không đc thc thi 1 cách đúng đn tron 1 vài trình duyt
(IE) vì vy ta không nên s dng nh vy
1.5.S leo thanh ca hàm function - Function Hoisting
t nhng tho lun trc đó, ta có th kt lun rng cách thc thc thi ca các khai báo
function là rt tuyt tng đng vi cách dùng 1 biu thc named function expression.điu
này không thc s chính xác và có 1 s khác bit nm trong s leo thang hoisting
nh ta đư bit, tt c các bin và không có th gi nm trong hàm function đư đc khai báo có
th leo thang lên đu hàm function .nhng ng dng ging vy đc áp dng cho hàm bi vì
chúng ch là các đi tng đc gán vào trong các bin.
// antipattern
// for illustration only
// global functions
function
foo() {
alert('global foo');
}
function bar() {
alert('global bar');
}
function hoistMe() {
Lp trình hng đi tng trong Javascript và các kiu mu thit k
Ngô Quang Trung – email: / www.phonegap.vn/forum 18
console.log(typeof foo); // "function"
console.log(typeof bar); //
"undefined"
foo(); // "local foo"
bar(); //
TypeError: bar is not a function
// function declaration:
// variable 'foo' and its implementation both get hoisted
function
foo() {
alert('local foo');
}
// function expression:
// only variable 'bar' gets hoisted
// not the implementation
var bar = function () {
alert('local bar');
};
}
hoistMe();
trong ví d trên ta thy rng, ging vi các bin thông thng, thì s hin din ca foo và bar
bt c đâu trong hàm hoistMe() function thì đu chuyn chúng lên trên đu và ghi đè vào
foo và bar toàn cc.đim khác bit là đnh ngha đa phng ca foo() đc leo thang lên đu
và hot đng bình thng còn đnh ngha ca bar() không đc leo thang và ch có đnh
ngha ca nó.đây là lí do ti sao cho ti khi đon mư code thc thi đn đnh ngha ca bar()
thì nó không xác đnh và không đc s dng nh 1 hàm function (trong khi nó vn cn tr
li bar() toàn cc)
S leo thang, s leo
thang không có tác
dng khi đc gán
trong 1 bin và ngc
li khi xy ra s leo
thang thì nó s ghi đè
lên giá tr bin toàn cc
Leo thang tht bi
Lp trình hng đi tng trong Javascript và các kiu mu thit k
Ngô Quang Trung – email: / www.phonegap.vn/forum 19
1.6.Kiu mu callback
hàm function là các đi tng objects, điu này có ngha là chúng có th đc chuyn tip
qua hàm functions khác.khi ta chuyn tip hàm function introduceBugs() nh là 1 tham s
trong hàm writeCode(), sau đó vài đim thì hàm writeCode() có th thc thi ( hay gi ) hàm
introduceBugs().trong trng hp này thì introduceBugs() đc gi là hàm callback :
function writeCode(callback) {
// do something
callback();
//
}
function
introduceBugs() {
// make bugs
}
writeCode(
introduceBugs);
chú ý ti cách mà hàm introduceBugs() đc chuyn tip nh 1 tham s ti hàm writeCode()
mà không có du ngoc.du ngoc thc thi 1 hàm function trái vi trng hp ta mun
chuyn tip ch 1 tham chiu ti hàm function và đ writeCode() thc thi nó ( hay cách khác
là gi li nó )
1.6.1.Mt ví d mu v callback
Chúng ta cn 1 ví d và bt đu không vi 1 hàm callback đu tiên và sau đó ta bàn ti nó
sau.đ hình dung ra, ta có 1 hàm theo mc đích thông thng mà làm 1 vài công vic biên
dch và tr v 1 tp các d liu ln nh 1 kt qu.hàm function thông thng này đc gi là
findNodes(), và tác v ca nó là bò trn lên cây DOM tree ca 1 trang page và tr v 1
mng các phn t ca trang page mà nó s cun hút ta :
var
findNodes = function () {
var i = 100000, // big, heavy loop
nodes = [], // stores the result
found; // the next node found
while (i) {
i -= 1;
// complex logic here
Lp trình hng đi tng trong Javascript và các kiu mu thit k
Ngô Quang Trung – email: / www.phonegap.vn/forum 20
nodes.push(found);
}
return nodes;
};
ây là 1 ý tng hay nhm gi hàm function này 1 cách chung nht và nó đn gin tr v 1
mng array ca DOM nodes mà không làm bt c gì khác vi các đi tng thc t.s logic
trong vic hiu chnh các nodes có th trong 1 hàm function khác ví d 1 hàm function gi là
hide() nh nhng gì tên nó gi ý thì nó dùng đ n các nodes trên page :
var
hide = function (nodes) {
var i = 0, max = nodes.length;
for (; i < max; i += 1) {
nodes[i].style.display = "none";
}
};
// executing the functions
hide(findNodes());
cách thc thi này là không có hiu nng x lý tt bi vì hide() phi lp li 1 ln na thông
qua các phn t trong mng nodes đc tr v bi hàm findNodes().nó s tr nên hiu qu
hn nu ta có th tránh vòng lp này và n đi các nodes ging nh vic ta chn ra chúng
trong hàm findNodes().nhng nu ta thc thi điu kin logic đ n trong findNodes(), thì nó
s không còn là 1 hàm function thông thng bi vì có s ghép cp ca điu kin logic nhn
v và điu kin logic hiu chnh.
Ta áp dng mu callback – ta chuyn tip điu kin logic đ n node nh 1 hàm callback và
y thác cho nó thc thi :
// refactored findNodes() to accept a callback
var findNodes = function (
callback) {
var i = 100000,
Hiu nng x lý không cao bi vì
ta phi duyt 2 ln mng nodes,
tc là thc hin vòng lp tn 2 ln
Lp trình hng đi tng trong Javascript và các kiu mu thit k
Ngô Quang Trung – email: / www.phonegap.vn/forum 21
nodes = [],
found;
// check if callback is callable
if (typeof callback !== "function") {
callback = false;
}
while (i) {
i -= 1;
// complex logic here
// now callback:
if (callback) {
callback(found);
}
nodes.push(found);
}
return nodes;
};
S thc thi này là hin nhiên, ch có 1 tác v b sung là findNodes() thc thi kim tra tham s
callback có đc thêm vào đúng hay không, nu đúng nó s thc thi.hàm callback là không
bt buc do vy hàm findNodes() vn có th đc s dng ging nh lúc trc mà không phá
v mư code c
Thc thi hide() s đc đn gin hóa hn bi vì nó không cn ti vòng lp thông qua các
nodes :
// a callback function
var hide = function (node) {
node.style.display = "none";
};
// find the nodes and hide them as you go
findNodes(hide);
Hiu nng x lý đc ci thin,
c 2 công vic đu đc thc hin
thông qua 1 vòng lp, ta va
duyt phn t trong mng nodes
và đng thi ngay sau đó n đi
các phn t đc duyt đó
Lp trình hng đi tng trong Javascript và các kiu mu thit k
Ngô Quang Trung – email: / www.phonegap.vn/forum 22
hàm callback có th là 1 hàm đư tn ti nh đư ch ra trong ví d trc hay nó có th là hàm
vô danh.ví d, ti đây cách mà ta có th ch ra các nodes bng cách s dng cùng hàm
findNodes() thông thng :
// passing an anonymous callback
findNodes(function (node) {
node.style.display = "block";
});
1.6.2.Hàm callback và phm vi tn ti ca bin trong hàm callback
Trong ví d trc, phn ni mà hàm callback đc thc thi là :
callback(parameters);
mc dù điu này khá là đn gin và s đ tt trong nhiu trng hp, đây thng là nhng
kch bn ni mà hàm callback không là 1 hàm vô danh hay là 1 hàm toàn cc, nhng nó là 1
phng thc ca 1 đi tng object.phng thc callback s dng this đ tham chiu ti đi
tng mà nó thuc v do vy điu này có th ny sinh ra cách thc thc thi không mong
mun
ví d hàm callback là hàm paint() là 1 phng thc ca đi tng có tên là myapp :
var
myapp = {};
myapp.color = "green";
myapp.paint = function (node) {
node.style.color = this.color;
};
The function findNodes() does something like this:
var findNodes = function (callback) {
//
if (typeof callback === "function") {
callback(found);
}
Lp trình hng đi tng trong Javascript và các kiu mu thit k
Ngô Quang Trung – email: / www.phonegap.vn/forum 23
//
};
Nu ta gi
findNodes(myapp.paint) thì nó s không hot đng nh mong đi bi vì
this.color s không đc đnh ngha.đi tng this s tham chiu ti đi tng toàn cc
global object bi vì findNodes() là 1 hàm toàn cc.nu findNodes() là 1 phng thc ca 1
đi tng gi là dom (dom.findNodes() ) thì this bên trong hàm callback s tham chiu ti
đi tng dom thay cho đi tng mà ta mun là myapp.
gii quyt vn đ này thì ta chuyn tip hàm callback và b sung chuyn tip đi tng
object mà hàm callback này thuc v nh sau :
findNodes(myapp.paint, myapp);
sau đó ta cng cn hiu chnh li findNodes() cho hàm này liên kt vi đi tng mà ta
chuyn tip vào :
var findNodes = function (callback, callback_obj) {
//
if (typeof callback === "function") {
callback.call(callback_obj, found);
}
//
};
1 la chn khác cho vic chuyn tip 1 đi tng và 1 phng thc đc s dng nh 1 hàm
callback là chuyn tip phng thc ging nh 1 chui string và do đó ta không phi vit lp
li đi tng 2 ln :
findNodes(myapp.paint, myapp);
chuyn thành :
findNodes("paint", myapp);
Lp trình hng đi tng trong Javascript và các kiu mu thit k
Ngô Quang Trung – email: / www.phonegap.vn/forum 24
hàm findNodes() cng phi sa li nh sau :
var findNodes = function (callback, callback_obj) {
if (typeof callback === "string") {
callback = callback_obj[callback];
}
//
if (typeof callback === "function") {
callback.call(callback_obj, found);
}
//
};
1.6.3.Lng nghe s kin không đng b
Kiu mu hàm callback đc s dng hàng ngày ví d khi ta đính thêm 1 đng ký s kin
event listener vào 1 phn t trên 1 trang page thì thc cht ta cung cp 1 con tr ch ti 1 hàm
callback mà s đc gi khi s kin xy ra.đây là 1 ví d đn gin v cách mà console.log()
đc chuyn tip nh 1 hàm callback khi lng nghe s kin click :
document.addEventListener("click", console.log, false);
hu ht cách lp trình hng client đu theo hng thc thi theo s kin.khi trang page đc
ti xong thì nó kích hot 1 s kin load.sau đó ngi dùng tng tác vi trang page và gây ra
1 vài s kin khác nhau ging nh click, keypress, mouseover, mousemove, ầJS v bn
cht là thích hp vi lp trình theo hng s kin bi vì kiu mu callback – cho phép
chng trình ca ta làm vic 1 cách không đng b
câu khu hiu ni ting Hollywood là “ đng gi cho chúng tôi mà chúng tôi s gi cho bn
“.có 1 điu không th cho nhóm tuyn chn là tr li tt c các cuc gi t tt c các ng viên
trong toàn thi gian.JS điu khin theo hng s kin k đng b và nó tng t nh vy.ch
bng cách thay th vic đa ra s đin thoi ca ta thì ta cung cp 1 hàm callback có th
đc gi khi đúng thi đim.ta cng có th cung cp nhiu hn các hàm callback nu cn.bi
vì rt có th có s kin nào đó không bao gi xy ra.ví d nu ngi dùng không bao gi
click vào “Buy now!” thì hàm function ca ta mà dùng đ kim tra tính hp l ca th thanh
toán s không bao gi đc gi
Lp trình hng đi tng trong Javascript và các kiu mu thit k
Ngô Quang Trung – email: / www.phonegap.vn/forum 25
1.6.4. tr Timeouts
1 ví d khác cho kiu mu callback là khi ta s dng phng thc timeout đc cung cp bi
windowobject: setTimeout() và setInterval().thì các phng thc này cng nhn và thc thi
các hàm callbacks :
var thePlotThickens = function () {
console.log('500ms later ');
};
setTimeout(thePlotThickens, 500);
chú ý li cách mà hàm thePlotThickens đc chuyn tip nh 1 bin mà không có du ngoc
bi vì ta không mun nó thc thi ngay lp tc nhng đn gin ch mun ch ti nó sau khi s
dng setTimeout().chuyn tip chui "thePlotThickens()" thay th cho 1 con tr hàm
function là 1 cách không kiu mu tng t vi eval().
1.6.5.Hàm callbacks trong các th vin
Hàm callback là kiu mu đn gin và rt mnh m, nó có th rt đ đ kim soát khi ta thit
k 1 th vin.mư code có trong th vin s tr nên khái quát và tái s dng li nhiu nht có
th và các hàm callbacks tr giúp vic khái quát hóa này.ta không cn d đoán và thc th
mi tính nng mà ta có th ngh ra bi vì nó s làm th vin ca ta phình to lên và hu ht
ngi s dng s không bao gi cn 1 lng ln các tính nng đó.đ thay th, ta tp trung
vào các chc nng chính và cung cp các “hooks” trong dng hàm callback mà cho phép các
phng thc ca th vin d dàng đc xây dng, m rng và tùy chnh
1.6.6.Cách tr v trong hàm functions
Các hàm functions là các đi tng objects vì vy chúng có th đc s dng và tr li các
giá tr.điu này có ngha là 1 hàm function không cn tr v 1 vài dng d liu hay 1 mng d
liu nh là kt qu ca quá trình thc thi ca nó.1 hàm function có th tr v hàm function c
th nào đó hay nó có th to ra 1 hàm function khác theo yêu cu ging nh sau :