2010-08-13 33 views
5

tôi mất này từ Google Code Sân chơi http://code.google.com/apis/ajax/playground/cách truy cập các biến trong đóng nếu có các biến cục bộ có cùng tên?

/*CLOSURE 
* When a function is defined in another function and it 
* has access to the outer function's context even after 
* the outer function returns 
* An important concept to learn in Javascript 
*/ 

function outerFunction(someNum) { 
    var someString = 'Hai!'; 
    var content = document.getElementById('content'); 
    function innerFunction() { 
    content.innerHTML = someNum + ': ' + someString; 
    content = null; // IE memory leak for DOM reference 
    } 
    innerFunction(); 
} 

outerFunction(1); 

/////////////////////// 

của nó tất cả ok, nhưng nếu tôi có một biến cục bộ trong hàm bên trong có cùng tên như là một biến trong chức năng bên ngoài sau đó làm thế nào để truy cập vào biến đó?

function outerFunction(someNum) { 
    var someString = 'Hai!'; 
    var content = document.getElementById('content'); 
    function innerFunction() { 
    var someString='Hello'; 
    content.innerHTML = someNum + ': ' + someString; 
    content = null; // IE memory leak for DOM reference 
    } 
    innerFunction(); 
} 

outerFunction(1); 
+0

Tại sao không đổi tên một trong số chúng? – kennytm

+0

Tôi đã chèn một dòng var ss = someString; bên trong hàm bên trong. Sau đó, khi tôi cố gắng truy cập ss nó trở về không xác định – Sriram

+0

Rất giống/trùng lặp? Câu hỏi: http://stackoverflow.com/questions/1484143/scope-chain-in-javascript –

Trả lời

8

Bạn không thể, vì biến của phạm vi bên ngoài bị bóng mờ bởi hàm bên trong chức năng bên trong của bạn.

Chuỗi phạm vi trên innerFunction trông giống như sau:

 

    innerFunction      outerFunction    global object 
______________________   ________________________  _______________ 
|* someString = 'Hello'| <---- | someString = 'Hai!' | <---|* outerFunction| 
----------------------  |* content = [HTMLElement]|  | .....  | 
           |* someNum (argument)  |  --------------- 
           |* innerFunction   | 
           ------------------------- 

* Denotes a resolvable identifier from the scope of innerFunction. 

Mỗi chức năng có riêng Biến đối tượng của nó, là nơi mà các định danh của Khai báo hàm, khai báo biến, và chức năng thông số chính thức sống, như tính chất.

Các đối tượng đó không thể truy cập trực tiếp bằng mã, chuỗi phạm vi được tạo thành bởi tất cả các đối tượng bị xích đó.

Khi số nhận dạng là resolved, tra cứu sẽ xuất hiện trong chuỗi phạm vi, tìm kiếm hình dạng đầu tiên của nó, cho đến khi đối tượng chung được tiếp cận, nếu không tìm thấy số nhận dạng, ReferenceError bị ném.

tặng một cái nhìn vào bài viết sau đây:

+0

Có công việc nào cho việc này không? – Sriram

+0

@Sriram - Thay đổi tên biến hoặc chuyển vào biến bên ngoài làm đối số. –

+0

@CMS - Bản vẽ của bạn đã bị hỏng: ( –

0

Hãy thử với this.varname để tham chiếu đến tài khoản đang đóng.

this.someString trong ví dụ của bạn.

+1

Ý nghĩa của biến 'this' phụ thuộc vào cách bên trong được gọi, do đó, điều này sẽ chỉ hoạt động nếu hàm chứa phạm vi đóng là ngữ cảnh mà hàm bên trong được gọi là phương thức. Nếu bạn truyền hàm đó cho một số đối tượng khác và sau đó gọi nó, mặc dù liên kết đến phần đóng vẫn còn đó, 'this' sẽ không trỏ đến nó. – thomasrutter

+0

Đúng. Tôi nhận ra điều đó và chuẩn bị xóa câu trả lời của riêng tôi, nhưng lời giải thích của bạn khiến nó đáng để ở lại. :) –

+0

Bạn có thể giải thích thêm một chút không? Tôi đã không nhận được những thứ 'này'! – Sriram

0

Bạn có thể

  • chỉ cần tránh tạo ra bất kỳ biến địa phương có cùng tên, hoặc
  • tạo một bản sao địa phương cho việc đóng cửa biến trước khai báo biến cục bộ của cùng tên (nếu bạn thực sự muốn có một biến địa phương cùng tên)

(có một cách giải quyết nhưng loại bỏ nó sau nó đã chỉ ra rằng nó sẽ không thực sự làm việc)

+0

Bạn không bao giờ gọi 'innerfunc()' chỉ bên ngoài. –

+1

'copyofmyvar' sẽ luôn là' undefined', tiến trình biến đổi diễn ra * trước * thực thi hàm thực tế, các biến gặp phải trong phạm vi được khởi tạo với 'undefined' và điều này xảy ra với' myvar' được định nghĩa trong phạm vi bên trong, được thêm vào đối tượng Variable và được khởi tạo với 'undefined', sau đó, hàm thực thi và thực hiện các phép gán và vào lúc đó' myvar' từ phạm vi bên ngoài đã bị che khuất. – CMS

+0

http://jsfiddle.net/tjYz5/ –

1

các biến cục bộ của việc đóng cửa "shadow" các biến cùng tên từ chức năng bên ngoài, vì vậy đây:

function outerFunction(s) { 
    var someString = 'Hai!'; 
    function innerFunction() { 
    var someString='Hello'; 
    alert(someString); 
    } 
    innerFunction(); 
} 
outerFunction(); 

will alert Hello.

Cách duy nhất để làm việc xung quanh nó là để đổi tên các biến của bạn, hoặc vượt qua trong biến bạn muốn làm việc với:

function outerFunction(s) { 
    var someString = 'Hai!'; 
    function innerFunction(outer) { 
    var someString='Hello'; 
    alert(outer); 
    } 
    innerFunction(someString); 
} 
outerFunction();   

Will alert Hai!

Để tìm hiểu về chuỗi phạm vi, take a look at this previous scope question.

0
function outerFunction(someNum) { 
var someString = 'Hai!'; 
var content = document.getElementById('content'); 
function innerFunction() { 
this.someString = 'Hello'; 
content.innerHTML = someNum + ': ' + someString; 
content = null; // IE memory leak for DOM reference 
} 
    innerFunction(); 

} outerFunction (1);

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