this in JavaScript in detail

  sonic0002        2013-05-09 18:35:12       3,958        0          English  简体中文  繁体中文  ภาษาไทย  Tiếng Việt 

คำว่า this ใน JavaScript มักจะสร้างความสับสนเสมอ และเป็นหนึ่งในกับดักที่พบบ่อยที่สุดใน JavaScript ซึ่งไม่ใช่การออกแบบที่ดีใน JavaScript (คุณสามารถอ้างอิงข้อบกพร่องในการออกแบบอื่นๆ ของ JavaScript ได้ ที่นี่) เนื่องจากคุณสมบัติ lazy binding ทำให้มันสามารถเป็น global object, current object หรือ... บางคนถึงกับหลีกเลี่ยงการใช้ this ใน JavaScript

จริงๆ แล้ว ถ้าคุณเข้าใจวิธีการทำงานของ this อย่างถ่องแท้ คุณจะรู้วิธีหลีกเลี่ยงกับดักเหล่านี้ มาดูกันว่า this ชี้ไปที่อะไรในสถานการณ์ต่อไปนี้

1. ในโค้ด global scope

alert(this)//window

this จะชี้ไปที่ global object (โดยปกติคือ window ใน web browsers) ในโค้ด global scope

2. ในการเรียกฟังก์ชันแบบ pure

function fooCoder(x) {
	this.x = x;
}
fooCoder(2);
alert(x);// Global variable x's value is 2

ในที่นี้ this ก็ชี้ไปที่ global object เช่นกัน เนื่องจากฟังก์ชันที่กำหนดไว้ใน global scope จริงๆ แล้วเป็น method หนึ่งของ global object ดังนั้น this จะเป็น global object ใน strict mode, this จะเป็น undefined

3. ในการเรียก method ของ object

var name = "clever coder";
var person = {
	name : "foocoder",
	hello : function(sth){
		console.log(this.name + " says " + sth);
	}
}
person.hello("hello world");

ผลลัพธ์จะเป็น "foocoder says hello world" this จะชี้ไปที่ person object นั่นคือ current object ที่เรียก method

4. ใน constructor

new FooCoder();

ใน constructor this จะชี้ไปที่ object ที่สร้างขึ้นใหม่ด้วย new

5. ในการเรียกฟังก์ชัน private

var name = "clever coder";
var person = {
	name : "foocoder",
	hello : function(sth){
		var sayhello = function(sth) {
			console.log(this.name + " says " + sth);
		};
		sayhello(sth);
	}
}
person.hello("hello world");//clever coder says hello world

ในฟังก์ชัน private, this ไม่ได้ binding กับ object ของ method ภายนอก แต่ binding กับ global object แทน ซึ่งถือเป็นข้อบกพร่องในการออกแบบของ JavaScript เพราะไม่มีใครต้องการให้ this ในฟังก์ชัน private ชี้ไปที่ global object ในที่นี้ วิธีแก้ปัญหาทั่วไปคือการกำหนด this ให้กับตัวแปรอื่นและอ้างอิงตัวแปรนั้นในฟังก์ชัน private

var name = "clever coder";
var person = {
	name : "foocoder",
	hello : function(sth){
		var that = this;
		var sayhello = function(sth) {
			console.log(that.name + " says " + sth);
		};
		sayhello(sth);
	}
}
person.hello("hello world");//foocoder says hello world

6. ใน call() หรือ apply()

person.hello.call(person, "world");

apply() และ call() คล้ายกัน ความแตกต่างเพียงอย่างเดียวคือ parameters ที่ส่งเข้ามาหลังจาก parameter แรก ใน apply(), parameters อื่นๆ จะถูกส่งด้วย array ในขณะที่ใน call(), parameters อื่นๆ จะถูกส่งแยกกัน

call( thisArg [,arg1,arg2,… ] );  // Parameter list,arg1,arg2,...
apply(thisArg [,argArray] );     // Parameter list,argArray

parameter แรกที่ส่งเข้ามาคือ object ที่ this จะชี้ไป เราสามารถระบุ object ใดๆ ที่จะให้ this ชี้ไปได้

7. อื่นๆ

เราอาจเห็นโค้ดด้านล่างนี้บ่อยๆ:

$("#some-ele").click = obj.handler;

ถ้าเราใช้ this ใน handler, this จะ bind กับ obj หรือไม่? เห็นได้ชัดว่าไม่ หลังจาก assignment, ฟังก์ชันจะถูกเรียกใน callback function, this จะ bind กับ $("#some-div") element นี่คือสิ่งที่เราต้องเข้าใจในที่นี้ -- execution context 

แล้วเราจะระบุ this object ให้เป็นสิ่งที่เราต้องการใน callback function ได้อย่างไร? ใน ECMAScript 5 มี method bind():

fun.bind(thisArg[, arg1[, arg2[, ...]]])

thisArg จะเป็น this object ที่เราต้องการให้เป็น

$("#some-ele").click(person.hello.bind(person));

ตอนนี้ this จะเป็น person object

ใน Prototype.js เราสามารถค้นหา implementation ของ bind() ได้:

Function.prototype.bind = function(){
  var fn = this, args = Array.prototype.slice.call(arguments), object = args.shift();
  return function(){
    return fn.apply(object,
      args.concat(Array.prototype.slice.call(arguments)));
  };
};

สรุป

1. เมื่อฟังก์ชันถูกเรียกเป็น method ของ object, this จะชี้ไปที่ object นั้น

2. เมื่ออยู่ใน pure function call, this จะเป็น global object (ใน strict mode, this จะเป็น undefined)

3. ใน constructor, this จะเป็น object ที่สร้างขึ้นใหม่

ในประโยคเดียว this จะชี้ไปที่ object ที่ฟังก์ชันถูกเรียกเสมอ

GUIDE  BIND  THIS  JAVASCRIPT 

           

  RELATED


  0 COMMENT


No comment for this article.



  PROGRAMMER HUMOR

Levels of programmer


  SUPPORT US