2010-04-08 32 views
20

Khi tôi gọi hàm, phạm vi cục bộ được dựng cho cuộc gọi đó. Có cách nào để trực tiếp tham chiếu phạm vi đó như một đối tượng không? Cũng giống như cửa sổ là một tham chiếu cho đối tượng phạm vi toàn cục.JavaScript: Tham chiếu phạm vi địa phương của hàm là đối tượng

Ví dụ:

function test(foo){ 
    var bar=1 
    //Now, can I access the object containing foo, bar, arguments and anything 
    //else within the local scope like this: 
    magicIdentifier.bar 
} 

Cách khác, không ai có một danh sách đầy đủ của những gì là trong phạm vi địa phương trên đầu trang của các biến tùy chỉnh?

Thông tin cơ bản: Tôi đang cố gắng chuyển sang phạm vi toàn cục từ bên trong một cuộc gọi hàm, câu lệnh bằng câu chuyện là một trò đùa, cuộc gọi hoạt động tốt hơn một chút, nhưng nó vẫn phá vỡ mọi thứ được khai báo trong hàm phạm vi nhưng không phải trong phạm vi toàn cầu, do đó tôi sẽ khai báo vài trường hợp này trong phạm vi toàn cầu, nhưng điều đó đòi hỏi tôi phải biết chúng là gì. Hàm execScript của IE thực hiện một sự thay đổi hoàn toàn, nhưng nó chỉ giải quyết được vấn đề cho IE.

Lưu ý: Đối với bất kỳ ai đang tải JavaScript động, setTimeout(code,1) là một hack đơn giản hiệu quả để đạt phạm vi toàn cầu, nhưng nó sẽ không thực thi ngay lập tức.

+0

Nếu bạn cần truy cập đối tượng chứa đối số 'foo' bên trong hàm tại sao không trực tiếp chuyển đối tượng này làm đối số? –

Trả lời

13

Không, không có cách nào để tham khảo các đối tượng biến của bối cảnh thực hiện một chức năngđối tượng ràng buộc của môi trường biến của bối cảnh thực hiện (đó là những gì mà nó được gọi là [bây giờ; vì thế gạch ngang chữ]; chi tiết trong §10.3 of the specification). Bạn chỉ có thể truy cập chế độ xem giới hạn đối với chế độ xem bạn nhận được với arguments (thực tế rất hạn chế).

Thông thường khi tôi muốn làm điều này, tôi chỉ cần đặt mọi thứ tôi muốn vào một đối tượng và sau đó sử dụng nó (ví dụ, chuyển nó vào một hàm). Tất nhiên, bất kỳ hàm nào được tạo trong ngữ cảnh đều có quyền truy cập vào mọi thứ trong phạm vi mà chúng được tạo ra, khi chúng "đóng lại" ngữ cảnh; thêm: Closures are not complicated.

+1

Wow, những thông số kỹ thuật đó thực sự là một nỗi đau để đọc. Trong mọi trường hợp, theo như tôi có thể nói, chúng dường như gợi ý rằng các biến cục bộ duy nhất ngoài các tham số và các locals được xác định là các đối số và độ dài. Điều đó sẽ giúp tôi di chuyển, cảm ơn bạn. Tôi đang xây dựng một thư viện và chức năng đầu tiên tôi tạo ra là phiên bản nhất quán của setInterval, đó là điều này là dành cho. Tất cả mọi thứ dường như phát triển phức tạp hơn rất nhiều khi bạn có để cung cấp một giao diện trừu tượng sáng bóng. – aaaaaaaaaaaa

+0

@eBusiness: Vâng, vâng. :-) Đừng quên bất kỳ hàm được đặt tên nào được khai báo trong hàm, đó cũng là các ký hiệu trong phạm vi. –

1

Một số phiên bản nhất định của Netscape có thuộc tính ma thuật trong đối tượng arguments đã làm những gì bạn đang tìm kiếm. (Tôi không thể nhớ những gì nó được gọi là)

+0

'arguments' là một biến chứa tất cả các đối số được truyền cho hàm hiện tại. – nickf

+1

@nickf: Tôi nhận ra điều đó. Trong một số phiên bản của Netscape, nó có một quyền sở hữu đặc biệt được gọi là phạm vi biến. – SLaks

+1

@nickf: Tôi cũng đọc nó lần đầu tiên, nhưng biết SLaks tôi đã đọc nó lần thứ hai và nhận ra ý của anh ấy là gì. :-) –

-2

Bạn không cần từ khóa để tham chiếu biến trong phạm vi địa phương, vì đó là phạm vi bạn đang ở trong.

+5

vâng, tôi nghĩ anh ấy muốn lặp lại chúng hoặc một cái gì đó ... – nickf

+1

Lặp lại tất cả các biến duy nhất tồn tại trong phạm vi hiện tại? Đó không phải là âm thanh Javascript (hoặc bất kỳ tương tự Javascript nào của từ "Pythonic") đối với tôi. –

+1

Không có đối tượng tham chiếu biến cục bộ âm thanh Không có Javascript với tôi. Tôi không cần nó nhưng tôi mong đợi nó tồn tại, JavaScript dường như có các đối tượng cho hầu như tất cả mọi thứ và được tất cả về các đối tượng. – Rolf

0

Còn thứ gì đó như thế này?

<script type="text/javascript"> 
    var test = { 
     bar : 1, 
     foo : function() { 
      alert(this.bar); 
     } 
    } 

    test.foo(); 
</script> 
+0

Nếu mục tiêu của tôi chỉ đơn giản là viết mã lẻ mà có thể là một giải pháp tốt đẹp :-) – aaaaaaaaaaaa

+0

Lol. Tôi không thấy làm thế nào nó là lẻ vì bạn chỉ cần tạo một cấu trúc lớp đơn giản. –

0

nếu bạn muốn thay đổi phạm vi chức năng cho bất kỳ đối tượng bạn có thể sử dụng thư viện gạch với _.bind

Trong trường hợp của bạn:

var fn = _.bind(function(){ 
    console.log(this == window) 
},window) 

fn() // true 
+2

Đó không phải là phạm vi chức năng, đó là 'điều này'. – aaaaaaaaaaaa

6

Tôi biết điều này là cực kỳ muộn, và có lẽ bạn thậm chí không quan tâm chút nào nữa, nhưng tôi cũng quan tâm đến tính khả thi của điều này và bạn có thể thực hiện một công việc nào đó bằng cách sử dụng:

(function(global) { 
    var testVar = 1; 

    global.scope = function(s) { 
     return eval(s); 
    } 
})(this); 

sau đó chạy:

scope('testVar'); // 1 

trả về biến từ bên trong đóng cửa.Không phải là đặc biệt tốt đẹp, nhưng về mặt lý thuyết có thể bọc trong một đối tượng, có lẽ sử dụng một số xác nhận và getters và setters nếu bạn cần?

Chỉnh sửa: Đã đọc lại câu hỏi, tôi cho rằng bạn muốn truy cập nó mà không phải chỉ định hàm trong phạm vi, vì vậy điều này có thể không áp dụng được. Tôi sẽ để điều này ở đây.

+1

Tôi nghĩ điều này thật tuyệt vời! –

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