2009-10-08 26 views
25

Tôi đang cố gắng hiểu tại sao trong javascript, bạn có thể muốn thay đổi ngữ cảnh của hàm. Tôi đang tìm kiếm một ví dụ thế giới thực hoặc một cái gì đó mà sẽ giúp tôi hiểu làm thế nào/tại sao kỹ thuật này được sử dụng và ý nghĩa của nó là gì.Cách thay đổi ngữ cảnh của hàm trong javascript

Kỹ thuật này được minh họa bằng ví dụ này (từ http://ejohn.org/apps/learn/#25)

var object = {}; 
function fn(){ 
    return this; 
} 
assert(fn() == this, "The context is the global object."); 
assert(fn.call(object) == object, "The context is changed to a specific object."); 
+13

Hài hước; Tôi tìm thấy trang này vì tôi cần đặt ngữ cảnh cho cuộc gọi mà tôi đang tạo và không thể nhớ cú pháp ... :) – rinogo

+1

+1 nên có tiêu đề: "Cách thay đổi ngữ cảnh của hàm trong javascript" (jk - cảm ơn vì đã đăng bài này!) –

+0

+1 Tôi đang tìm cách duy trì sự nhất quán này trong một lớp ... – LoremIpsum

Trả lời

20

jQuery tận dụng nó để hiệu quả tốt:

$('a').each(function() { 
    // "this" is an a element - very useful 
}); 

Mã jQuery thực tế trông như thế này:

for (name in object) { 
    if (callback.call(object[ name ], name, object[ name ]) === false) { 
     break; 
    } 
} 

Nếu chỉ cần callback(name, object[ name ]) thì this sẽ không được đặt cho đối tượng hiện tại trong trình lặp của bạn và bạn phải sử dụng tham số thay thế. Về cơ bản nó chỉ làm mọi thứ dễ dàng hơn.

+2

Chỉ cần rõ ràng, tham số đầu tiên '.call()' trở thành 'this'. Chi tiết khác @ https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call – EpicVoyage

6

hãy có một cái nhìn vào ví dụ này:

<script> 
var el = document.getElementById('button'); 
el.onclick = function(){ 
    this.value = "Press Me Again"; //this --> now refers to the the element button not on the window 
} 

//Another Example: 
var Person = function(name,location){ 
    this.name = name; 
    this.location = location; 
    alert(this.location); 
} 
var p2 = new Person("Samantha","California"); //this refers to the instance of the function Person(Person now acts as a class) 
var p1 = Person(); // this refers to the window(Person simply acts as a simple function) 
</script> 
<button id="button1">Press Me</button> 

Từ khóa mới thay đổi bối cảnh.

3

Nó rất hữu ích khi thực hiện callbacks từ yêu cầu AJAX:

function Person(_id, _name) { 
    this.id = _id; 
    this.name = _name; 
}; 

Person.prototype.sayHi = function(greeting) { 
    alert(greeting + " from " + this.name); 
}; 

Person.prototype.loadFromAJAX = function(callback) { 
    // in this example, it's jQuery, but could be anything 
    var t = this; 
    $.get("myurl.php", function(data) { 
     callback.call(t, data.greeting); 
    }); 
}; 

Trên thực tế, đó là một ví dụ khá crappy.

Có rất nhiều công dụng trong jQuery. Ví dụ, hàm jQuery(). Get():

get: function(num) { 
    return num === undefined ? 
     // Return a 'clean' array 
     Array.prototype.slice.call(this) : 
     // Return just the object 
     this[ num ]; 
} 

Nó sử dụng các hàm của nguyên mẫu Array nhưng trong ngữ cảnh của đối tượng jQuery.

3

Một ví dụ thế giới thực mà tôi đã gặp phải:

Nếu bạn thêm một chức năng như một xử lý sự kiện cho một phần tử DOM và nếu bạn sử dụng "này" bên trong chức năng đó, "này" sẽ tham khảo các DOM mà bạn đã thêm trình xử lý sự kiện vào. Bạn có thể thay đổi ngữ cảnh để "này" sẽ không tham khảo các yếu tố DOM DOM nhưng sẽ tham chiếu đến đối tượng chủ sở hữu chủ sở hữu.

Bạn có thể dễ dàng thay đổi ngữ cảnh của hàm trong jquery bằng cách sử dụng hàm proxy(). Xem câu hỏi này: jquery "this" binding issue on event handler (equivalent of bindAsEventListener in prototype) và câu trả lời đầu tiên

0

tôi luôn luôn tìm thấy bản thân mình trong sự cần thiết của việc có bối cảnh khác nhau khi sử dụng setTimeout và jQuery có một chức năng tiện dụng $.proxy mà hiện các trick:

function iAmCalledAfterTimeout() 
{ 
    alert(this.myProperty); //it will alert "hello world" 
}  

setTimeout($.proxy(iAmCalledAfterTimeout, {myProperty:"hello world"}), 1000); 
1

ràng buộc chức năng có thể là những gì bạn đang tìm kiếm, hàm bind trả về một hàm mới trong ngữ cảnh mà bạn truyền vào, một kịch bản thế giới thực có thể là khi bạn sử dụng các ủy nhiệm jquery để đính kèm một số hành vi vào một phần tử dom, và bạn muốn gọi lại đang được thực thi trong một ngữ cảnh khác. vì bối cảnh mặc định trong một jquery delgate là đối tượng dom bị ràng buộc với trình xử lý, có nghĩa là bạn không thể truy cập bất kỳ thuộc tính nào bên cạnh các thuộc tính của đối tượng dom

Các vấn đề liên quan