2009-01-19 38 views
124

Tôi có một sự hiểu biết khá tốt về Javascript, ngoại trừ việc tôi không thể tìm ra cách tốt nhất để đặt biến "this". Hãy xem xét:Đặt biến "này" dễ dàng?

var myFunction = function(){ 
    alert(this.foo_variable); 
} 

var someObj = document.body; //using body as example object 
someObj.foo_variable = "hi"; //set foo_variable so it alerts 

var old_fn = someObj.fn; //store old value 
someObj.fn = myFunction; //bind to someObj so "this" keyword works 
someObj.fn();    
someObj.fn = old_fn;  //restore old value 

Có cách nào để thực hiện điều này mà không có 4 dòng cuối cùng không? Nó khá khó chịu ... Tôi đã cố gắng ràng buộc một chức năng vô danh, mà tôi nghĩ là đẹp và thông minh, nhưng vô ích:

var myFunction = function(){ 
    alert(this.foo_variable); 
} 

var someObj = document.body;  //using body as example object 
someObj.foo_variable = "hi";  //set foo_variable so it alerts 
someObj.(function(){ fn(); })(); //fail. 

Rõ ràng, chuyển biến vào myFunction là một lựa chọn ... nhưng đó là không phải là điểm của câu hỏi này.

Cảm ơn.

Trả lời

207

Có hai phương pháp định nghĩa cho tất cả các chức năng trong JavaScript, call(), và apply(). Cú pháp chức năng trông giống như:

call(/* object */, /* arguments... */); 
apply(/* object */, /* arguments[] */); 

gì các chức năng này làm là gọi hàm họ đã viện dẫn trên, gán giá trị của đối tượng tham số để này.

var myFunction = function(){ 
    alert(this.foo_variable); 
} 
myFunction.call(document.body); 
+3

Ngoài ra, nếu bạn đang sử dụng jQuery, bạn có thể sử dụng '$ .proxy (hàm, phần tử)' để bất cứ khi nào mà functio n được gọi, nó sẽ ở trong ngữ cảnh của phần tử. http://api.jquery.com/jquery.proxy/ –

54

Tôi nghĩ rằng bạn đang tìm kiếm call:

myFunction.call(obj, arg1, arg2, ...); 

này gọi myFunction với this thiết lập để obj.

Ngoài ra còn có phương pháp hơi khác nhau apply, trong đó có các thông số chức năng như một mảng:

myFunction.apply(obj, [arg1, arg2, ...]); 
+1

Xem phần 15.3.4.3, 15.3.4.4 và 10.1.8 trong ECMAScript Ngôn ngữ Thông số kỹ thuật: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf – some

15

Nếu bạn muốn 'cửa hàng' giá trị this đến một chức năng để bạn có thể gọi nó là liên tục sau đó (ví dụ như khi bạn không có quyền truy cập vào giá trị nữa), bạn có thể bind nó (không có sẵn trong tất cả các trình duyệt mặc dù):

var bound = func.bind(someThisValue); 

// ... later on, where someThisValue is not available anymore 

bound(); // will call with someThisValue as 'this' 
+5

FYI 'bind' có sẵn trong IE9 +, FF4 +, Safari 5.1.4+ và Chrome 7+ [(source)] (http: //kangax.github. io/es5-compat-table/# Function.prototype.bind). Bạn cũng có thể gọi liên kết trực tiếp trên một hàm ẩn danh: 'var myFunction = function() {/ * this = something * /} .bind (something);' – Adam

0

tìm kiếm của tôi về cách để ràng buộc this mang tôi đến đây vì vậy tôi đăng những phát hiện của tôi: trong 'ECMAScript 2015' chúng ta cũng có thể thiết lập này lexically sử dụng chức năng mũi tên để.

Xem: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions

Thay vì:

function Person() { 
    setInterval(function growUp() { 
    // The callback refers to the `self` variable of which 
    // the value is the expected object. 
    this.age++; 
    }.bind(this), 1000); 
} 

Bây giờ chúng ta có thể làm:

function Person(){ 
    this.age = 0; 

    setInterval(() => { 
    this.age++; // |this| properly refers to the person object 
    }, 1000); 
} 

var p = new Person(); 
Các vấn đề liên quan