หน้าเว็บ

วันจันทร์ที่ 4 พฤศจิกายน พ.ศ. 2556

คำสั่ง call และ apply javascript

        call และ apply มีหน้าที่การทำงานเหมือนกัน  คือ
"เอาไว้เรียกใช้งาน method javascript ที่ต้องการ  โดยสามารถส่ง parameter ผ่านทาง call และ apply ไปยัง method นั้นๆ ได้"

        สิ่งที่แตกต่างกันคือ 
call ส่งผ่าน parameter แบบ one by one ไปยัง method ที่ถูกเรียก (ส่วนมากจะใช้ในกรณีที่รู้ parameter แบบแน่นอนตายตัว)
ส่วน apply  จะส่งผ่าน parameter แบบ array ไปยัง method ที่ถูกเรียก (ใช้ในกรณีที่ parameter เป็นแบบ dynamic : http://na5cent.blogspot.com/2013/04/dynamic-callback-argument-javascript.html

call และ apply สามารถเปลี่ยน context ของ method ที่ถูกเรียกได้  โดยการส่ง context จากภายนอกเข้าไปแทน context ภายใน

มาดูตัวอย่างการใช้งานกันดีกว่า ผมขอยกตัวอย่างง่ายๆ  เพื่อง่ายต่อความเข้าใจน่ะครับ
var Computation = function(a, b){
   this.a = a || 0;
   this.b = b || 0;
};

Computation.prototype.add = function(a, b){
   this.a = a || this.a;
   this.b = b || this.b;

   return this.a + this.b;
};

Computation.prototype.minus = function(a, b){
   this.a = a || this.a;
   this.b = b || this.b;

   return this.a - this.b;
};
การเรียกใช้แบบทั่วๆ ไป ก็ไม่มีอะไรมากครับ

var compute = new Computation(3, 2);
console.log('compute.add() --> ' + compute.add());
console.log('compute.minus() --> ' + compute.minus());
console.log(compute);

//compute.add() --> 5 
//compute.minus() --> 1 
//Computation {a: 5, b: 1, add: function, minus: function}

console.log('compute.add() --> ' + compute.add(20, 1));
console.log('compute.minus() --> ' + compute.minus(20, 1));
console.log(compute);

//compute.add(20, 10) --> 30 
//compute.minus(20, 10) --> 10 
//Computation {a: 30, b: 10, add: function, minus: function}
ต่อมา ลองใช้ call ครับ
var compute = new Computation(3, 2);

var callObject = {
   a : 30,
   b : 20
};

//เปลียน context จาก this --> callObject
//ทำให้ this.a (3) อ้างถึง callObject.a (30)
//และ this.b  (2) อ้างถึง callObject.b (20)
console.log('compute.add.call(callObject) --> ' + compute.add.call(callObject));
console.log('compute.minus.call(callObject) --> ' + compute.minus.call(callObject));
console.log(callObject);
console.log(compute);

//compute.add.call(callObject) --> 50 
//compute.minus.call(callObject) --> 10 
//Object {a: 30, b: 20} 
//Computation {a: 3, b: 2, add: function, minus: function}



//เปลียน context จาก this --> callObject
//ทำให้ this.a (3) อ้างถึง callObject.a (30)
//และ this.b  (2) อ้างถึง callObject.b (20)
//จากนั้นส่งผ่าน parameter a (300) และ b (200) จากภายนอกเข้าไป
console.log('compute.add.call(callObject) --> ' + compute.add.call(callObject, 300, 200));
console.log('compute.minus.call(callObject) --> ' + compute.minus.call(callObject, 300, 200));
console.log(callObject);
console.log(compute);

//compute.add.call(callObject) --> 500 
//compute.minus.call(callObject) --> 100
//Object {a: 300, b: 200} 
//Computation {a: 3, b: 2, add: function, minus: function}
ต่อมา ลองใช้ apply ดูครับ
var compute = new Computation(3, 2);

var applyObject = {
   a : 100,
   b : 50
};

//เปลียน context จาก this --> applyObject
//ทำให้ this.a (3) อ้างถึง applyObject.a (100)
//และ this.b  (2) อ้างถึง applyObject.b (50)
console.log('compute.add.apply(applyObject) --> ' + compute.add.apply(applyObject));
console.log('compute.minus.apply(applyObject) --> ' + compute.minus.apply(applyObject));
console.log(applyObject);
console.log(compute);

//compute.add.call(applyObject) --> 150
//compute.minus.call(applyObject) --> 50
//Object {a: 100, b: 50} 
//Computation {a: 3, b: 2, add: function, minus: function}



//เปลียน context จาก this --> applyObject
//ทำให้ this.a (3) อ้างถึง applyObject.a (100)
//และ this.b  (2) อ้างถึง applyObject.b (50)
//จากนั้นส่งผ่าน parameter a (1000) และ b (500) จากภายนอกเข้าไป
console.log('compute.add.apply(applyObject) --> ' + compute.add.apply(applyObject, [1000, 500]));
console.log('compute.minus.apply(applyObject) --> ' + compute.minus.apply(applyObject, [1000, 500]));
console.log(applyObject);
console.log(compute);

//compute.add.call(applyObject) --> 1500
//compute.minus.call(applyObject) --> 500
//Object {a: 1000, b: 500} 
//Computation {a: 3, b: 2, add: function, minus: function}
คำถาม แล้วจะเอามาใช้ทำอะไร ?

        ผมเอามาใช้ทำ javascript OOP ครับ  เนื่องจาก javascript นั้นไม่มี OOP มาให้ตั้งแต่แรก  เราเลยต้องสร้าง OOP ขึ้นมาใช้งานเอง  ถึงจะมี library ต่างๆมากมายที่เขาทำไว้แล้ว  แต่ผมก็ยังอยากที่จะสร้างเองอยู่ดีครับ  เพราะผมอยากรู้ลึก รู้จริงในสิ่งที่ผมต้องใช้งานมันอยู่ประจำครับ  ผมอยากได้ชื่อว่าเป็นผู้สร้างมากกว่าผู้ใช้งาน

มาดูตัวอย่าง code ที่ผมใช้งานจริงกันครับ  ประมาณนี้

ตัวอย่าง  คำสั่ง call

จากภาพเป็น เป็นการประกาศ class PhotoViewerDialog ขึ้นมา  สังเกตตรง ลูกศรสีแดง method constructor

PhotoViewerDialog.superClass.constructor.call(this, element);

เป็นการเรียกใช้งาน method contructor ของ superClass โดยใช้ context (this) ของ class ลูก และส่งต่อ parameter element จาก class ลูกไปยัง superClass ด้วย


ตัวอย่าง  คำสั่ง apply

        เมื่อมีการ new instance ของ class PhotoViewerDialog เกิดขึ้น  เช่น

var dialog = new PhotoViewerDialog('#photoViewer');

ก็จะทำการส่ง parameter หรือ arguments ('#photoViewer') จาก Class (PhotoViewerDialog) ไปยัง method contructor ที่เราได้ทำการประกาศไว้  โดยใช้ context เป็น this ซึ่งก็คือ instance ปัจจุบัน (dialog) ที่ถูก new ขึ้นมานั่นเองครับ


ไม่มีความคิดเห็น:

แสดงความคิดเห็น