this in JavaScript in detail

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

Trong JavaScript, this luôn gây nhầm lẫn, nó là một trong những cạm bẫy thường thấy nhất. this không phải là một thiết kế tốt trong JavaScript (bạn có thể tham khảo một số sai sót thiết kế khác của JavaScript tại đây), vì tính năng liên kết trễ của nó, nó có thể là một đối tượng toàn cục, đối tượng hiện tại hoặc.... Một số người thậm chí tránh sử dụng this trong JavaScript.

Thực tế, nếu bạn nắm vững cách this hoạt động, bạn sẽ biết cách tránh xa những cạm bẫy này. Hãy xem this trỏ đến đâu trong các tình huống dưới đây.

1. Trong mã phạm vi toàn cục

alert(this)//window

this sẽ trỏ đến đối tượng toàn cục (thường là window trong trình duyệt web) trong mã phạm vi toàn cục.

2. Trong một lệnh gọi hàm thuần túy

function fooCoder(x) {
	this.x = x;
}
fooCoder(2);
alert(x);// Biến toàn cục x có giá trị là 2

Ở đây, this cũng đang trỏ đến đối tượng toàn cục vì hàm được định nghĩa trong phạm vi toàn cục thực chất là một phương thức của đối tượng toàn cục. Vì vậy, this sẽ là đối tượng toàn cục. Trong chế độ nghiêm ngặt, this sẽ là undefined.

3. Trong một lệnh gọi phương thức của một đối tượng

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

Kết quả sẽ là "foocoder says hello world". this sẽ trỏ đến đối tượng person, tức là đối tượng hiện tại gọi phương thức.

4. Trong một hàm tạo

new FooCoder();

Trong một hàm tạo, this sẽ trỏ đến đối tượng mới được tạo bằng new.

5. Trong một lệnh gọi hàm riêng tư

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

Trong một hàm riêng tư, this không liên kết đối tượng của phương thức bên ngoài, thay vào đó nó liên kết với đối tượng toàn cục. Điều này được coi là một sai sót thiết kế của JavaScript vì không ai muốn this trong hàm riêng tư trỏ đến đối tượng toàn cục ở đây. Giải pháp chung là gán this cho một biến khác và tham chiếu biến đó trong hàm riêng tư.

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. Trong call() hoặc apply()

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

apply()call() tương tự nhau, sự khác biệt duy nhất là các tham số được truyền vào sau tham số đầu tiên. Trong apply(), các tham số khác sẽ được truyền bằng một mảng, trong khi trong call(), các tham số khác được truyền riêng lẻ.

call( thisArg [,arg1,arg2,… ] );  // Danh sách tham số,arg1,arg2,...
apply(thisArg [,argArray] );     // Danh sách tham số,argArray

Tham số đầu tiên được truyền vào là đối tượng mà this sẽ trỏ đến. Chúng ta có thể chỉ định bất kỳ đối tượng nào để được trỏ đến bởi this.

7. Khác

Chúng ta có thể thấy đoạn mã dưới đây thường xuyên:

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

Nếu chúng ta sử dụng this trong handler, this sẽ liên kết với obj? Rõ ràng là không, sau khi gán, các hàm được gọi trong hàm gọi lại, this sẽ liên kết với phần tử $("#some-div"). Đây là điều chúng ta cần hiểu ở đây - ngữ cảnh thực thi. 

Vậy làm cách nào để chúng ta chỉ định đối tượng this là đối tượng chúng ta muốn trong hàm gọi lại? Trong ECMAScript 5, có một phương thức bind():

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

thisArg sẽ là đối tượng this mà chúng ta muốn.

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

Bây giờ this sẽ là đối tượng person

Trong Prototype.js, chúng ta có thể tìm thấy cách triển khai của 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)));
  };
};

Kết luận

1. Khi hàm được gọi là một phương thức của một đối tượng, this sẽ trỏ đến đối tượng đó

2. Khi trong một lệnh gọi hàm thuần túy, this sẽ là đối tượng toàn cục (trong chế độ nghiêm ngặt, this sẽ là undefined)

3. Trong một hàm tạo, this sẽ là đối tượng mới được tạo

Trong một câu, this sẽ luôn trỏ đến đối tượng mà hàm được gọi trên đó.

GUIDE  BIND  THIS  JAVASCRIPT 

           

  RELATED


  0 COMMENT


No comment for this article.



  PROGRAMMER HUMOR

Texting in class

How to send SMS safely in class. New skill get

  SUPPORT US