2012-05-22 35 views
12

Có vấn đề khi tham chiếu một đối tượng theo nghĩa đen trong một hàm là một phần của chữ đó? Dường như nó hoạt động tốt, nhưng tôi muốn đảm bảo không có những tác động khác.Javascript: Tham chiếu văn bản đối tượng trong chức năng của khóa riêng thay vì 'this'

Dưới đây là một ví dụ về những gì tôi đang nói về:

thay vì:

var obj = { 
    key1: "it", 
    key2: function(){return this.key1 + " works!"} 
}; 
alert(obj.key2()); 

sử dụng:

var obj = { 
    key1: "it", 
    key2: function(){return obj.key1 + " works!"} 
}; 
alert(obj.key2()); 

Trả lời

16

Cả hai đều có thể có vấn đề.

var obj = { 
    key1: "it", 
    key2: function(){ return this.key1 + " works!" } 
}; 
var func = obj.key2; 
alert(func()); // error 

Khi func không được gọi là một phương pháp obj, this có thể tham khảo cái gì khác (ở đây: đối tượng toàn cầu "window").

var obj = { 
    key1: "it", 
    key2: function(){ return obj.key1 + " works!" } 
}; 
var newref = obj; 
obj = { key1: "something else"; }; 
alert(newref.key2()); // "something else works" 

Ở đây, chúng tôi truy cập đối tượng từ tham chiếu khác, mặc dù obj trong hàm hiện có thể trỏ đến một số đối tượng khác.

Vì vậy, bạn sẽ phải chọn trường hợp nào có nhiều khả năng hơn. Nếu bạn thực sự muốn làm cho nó an toàn, bạn có thể sử dụng một đóng cửa nơi obj có phạm vi và không thể thay đổi:

var obj = (function(){ 
    var local = { 
     key1: "it", 
     key2: function(){ return local.key1 + " works always!" } 
    }; 
    return local; 
})(); 

hoặc bạn bind() chức năng cho các đối tượng:

var obj = { 
    key1: "it", 
    key2: function(){ return this.key1 + " works always!" } 
} 
obj.key2 = obj.key2.bind(obj); 
0

Tôi không nghĩ có bất kỳ ý nghĩa ra khỏi đầu đầu của tôi. Chỉ cần đảm bảo bạn không vô tình làm điều này tại bất kỳ thời điểm nào:

var obj = { 
    key1: "it", 
    key2: key1 + " works!" 
} 

Vì điều đó sẽ gây ra lỗi. Khác hơn thế, bạn nên được tốt để đi!

1

Sẽ có sự khác biệt trong liên kết phạm vi biến. Nếu bạn sửa đổi obj sau đó, bạn sẽ thay đổi giá trị trả về của khóa2:

var newobj = obj; 
obj = { key1: "new" }; 
alert(newobj.key2()); 

Bây giờ nó cảnh báo "! Tác phẩm mới", bởi vì mặc dù bạn đang gọi key2() trên đối tượng ban đầu (mà bây giờ là newobj), các tham chiếu đến obj.key1 hiện liên kết với giá trị của phiên bản obj mới. Sử dụng this ngăn điều này xảy ra.

Demo: http://jsfiddle.net/m6CU3/

1

Nếu bạn không sử dụng đối tượng nguyên mẫu, bạn czn đi như thế. vì mọi trường hợp đối tượng của bạn sẽ trả lại giá trị của cá thể obj ...

1

Hoặc hay cả hai kỹ thuật đó đều có thể áp dụng tùy theo tình huống.

Giá trị của this trong một hàm phụ thuộc vào cách hàm được gọi.Nếu bạn gọi hàm là thuộc tính của đối tượng như sau:

obj.key2(); 
//or 
obj["key2"](); 

Sau đó, this sẽ là đối tượng đó. Cho dù đối tượng đã được tạo thông qua một đối tượng theo nghĩa đen hoặc một số phương tiện khác không có liên quan.

Nhưng bạn có thể sử dụng .call() hoặc .apply() để gọi hàm và đặt rõ ràng this cho một số đối tượng khác.

cũng xem xét:

var obj = { 
    key1: "it", 
    key2: function(){return this.key1 + " works!"} 
}; 
alert(obj.key2()); // alerts "it works!" 

var func = obj.key2; 
alert(func())​;  // alerts "undefined works!" 

Tôi đang thiết lập func để tham khảo các chức năng tương tự như obj.key2, nhưng gọi nó như func() không không thiết this để obj.

Để biết thêm thông tin, hãy xem what MDN has to say about this.

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