2012-08-14 33 views
10

dụ:Điều gì sẽ xảy ra với biến "var" bên trong Trình tạo JavaScript?

function Foo() { 
    this.bla = 1; 
    var blabla = 10; 
    blablabla = 100; 
    this.getBlabla = function() { 
     return blabla; // exposes blabla outside 
    } 
} 

foo = new Foo(); 

gốc câu hỏi:

Tôi biết bla rằng sẽ được gán cho mỗi thể hiện của Foo. Điều gì sẽ xảy ra với blabla?

mới câu hỏi:

những gì tôi hiểu bây giờ:

this.bla = 1;  // will become an attribute of every instance of FOO. 
var blabla = 10; // will become a local variable of Foo(**not** an attribute of every instance of FOO), which could be accessed by any instance of FOO only if there's a method like "this.getBlabla". 
blablabla = 100; // will define a **new** (or change if exist) global(window) variable. 

        Did i understand correctly? 
+0

Ví dụ đã chỉnh sửa của bạn là chính xác - XÁC NHẬN rằng 'blabla' là UNIQUE để MỌI TRẢ LỜI của' Foo'. Vì vậy, nếu 'Foo' trông giống như' hàm Foo (số) {var blabla = number; this.bla = 37; this.getBlaBla = function() {return blabla; }; } 'sau đó' myFoo = new Foo (32); 'và' yourFoo = new Foo (47); 'sẽ có các giá trị hoàn toàn khác nhau cho' .getBlaBla() '. 'myFoo.getBlaBla() === 32; yourFoo.getBlaBla() === 47; 'Điều quan trọng cần nhớ là mặc dù nó là một' giá trị có phạm vi cục bộ' mà nó là duy nhất cho mỗi cá thể, và sẽ không có cùng giá trị cho bất kỳ Foo nào để đọc/ghi theo cách chia sẻ. – Norguard

Trả lời

8

Bất kỳ nội-các phương pháp bạn cung cấp cho this - ví dụ: this.method = function() {};trong khi bên hàm constructor Foo của bạn, là tất cả sẽ có một tham chiếu đến blahblah là duy nhất cho mỗi phiên bản của đối tượng Foo.

function Wallet() { 
    var balance = 0; 
    this.checkBalance = function() { return balance; }; 
    this.depositAmount = function (amount) { balance += amount; }; 
} 


var wallet = new Wallet(); 
wallet.checkBalance(); // 0 
wallet.depositAmount(3); 
wallet.checkBalance(); // 3 

Nhưng nó hoàn toàn được bảo vệ khỏi quyền truy cập bên ngoài ví, trừ khi bạn trả lại cho ai đó, từ một chức năng đặc quyền.

wallet.balance; // undefined; 

(thêm chút quan tâm - nếu balance là một string, một number, hoặc một boolean, ngay cả khi bạn quay trở lại nó, đó sẽ không từ bỏ người chỉnh sửa quyền, hoặc thậm chí truy cập xem vĩnh viễn - vô hướng biến được truyền theo giá trị, vì vậy bạn chỉ cần đi qua các giá trị cân bằng lúc - tuy nhiên, nếu, cân bằng là một object, một function hoặc một array, họ sẽ có quyền truy cập vĩnh viễn thay đổi các crap ra khỏi hoạt động nội bộ của bạn)

Lưu ý: phương pháp để được chỉ định bên trong hàm tạo để làm việc này. Nguyên mẫu không thể truy cập các biến nội bộ. Thêm phương pháp sau sẽ không cấp cho họ quyền truy cập vào các biến nội bộ.

Điều này có nghĩa là mỗi trường hợp sẽ chiếm nhiều bộ nhớ hơn một chút, vì mỗi bản sao đều có bản sao phương pháp riêng và có bản sao riêng của các vars. Nhưng nếu những gì bạn đang làm yêu cầu dữ liệu cá nhân, đây sẽ là một cách hay để có được nó.

+0

cảm ơn. vì vậy nếu tôi tạo ra một ví dụ anoter "var myOtherWallet = new Wallet(); sau đó nó sẽ làm cho một đóng cửa trong bộ nhớ bao gồm một" var balance = 0 "? – Daniel

+0

@ user1598423: Vâng, mỗi khi bạn chạy constructor nó sẽ tạo ra một biến cục bộ mới, và khi bạn kết hợp các phương thức với đối tượng như vậy, mỗi đối tượng sẽ có các cá thể của riêng các phương thức của nó, với các đóng riêng của chúng. – Guffa

2

Nó sẽ trở thành một địa phương (nghĩ về 'tư nhân') biến trong Foo(). Có nghĩa là bạn không thể truy cập nó bên ngoài Foo().

function Foo() { 
    this.bla = 1; // this becomes an extension of Foo() 
    var blabla = 10; // this becomes a "Local" (sort of like a 'private') variable 
} 

Bạn có thể hiển thị nó (bằng cách trả lại) bằng phương pháp Foo.

function Foo() { 
    var blabla = 10; // local 

    this.getBlabla = function() { 
     return blabla; // exposes blabla outside 
    } 
} 

Bây giờ bên ngoài của Foo():

var FooBar = new Foo(); 

var what_is_blabla = FooBar.getBlabla(); //what_is_blabla will be 10 

jsFiddle demonstration

+2

Đó là biến ** cục bộ **. Tôi sẽ tránh sử dụng thuật ngữ "riêng tư" vì nó được sử dụng khi nói về khả năng hiển thị trong các ngôn ngữ khác (một cái gì đó JavaScript không có). –

+1

Bạn có thể thêm các hàm được hiển thị khác có thể truy cập 'blabla'. Vì vậy, bằng cách thêm 'this.method = function() {return blabla; }; ', ta có thể lấy nội dung của' blabla'. – Sirko

+1

Tốt gọi Felix, quên có kỹ thuật không phải là bất kỳ "privates". Đã thực sự chỉ cần thêm rằng công cụ Sirko quá! –

1

Đó biến là địa phương để các nhà xây dựng và sẽ không được bên ngoài tiếp cận phạm vi đó (có thể là thông qua this hoặc), trừ khi nó bị bắt bởi một đóng cửa.

1

Biến được khai báo với var bên trong hàm được sử dụng làm hàm tạo, giống như tất cả các biến khác được khai báo với var bên trong bất kỳ hàm nào, chỉ hiển thị trong khi thực thi hàm đó (trừ khi giá trị được đóng bằng cách sử dụng đóng).

Nói cách khác, blabla không thể nhìn thấy bên ngoài các chức năng:

var foo = new Foo(); 
console.log(foo.bla);  // 1 
console.log(foo.blabla); // throws NameError 

Bằng việc xác định chức năng mà đóng trên các biến này, họ trở thành những điều gần gũi nhất JavaScript phải "tin" biến:

function Foo() { 
    this.bla = 1; 
    var private = 1; 

    this.increment = function() { 
     ++private; 
    } 

    this.getPrivateValue = function() { 
     return private; 
    } 
} 

foo = new Foo(); 
console.log(foo.bla);    // 1 
foo.bla = 6;       // legal 
console.log(foo.bla);    // 6 
console.log(foo.getPrivateValue()); // 1 
// console.log(foo.private);   // would throw an error 
foo.increment();      // legal 
console.log(foo.getPrivateValue()); // 2 
// foo.getPrivateValue() = 5;  // syntax error. Still can't reassign to private no matter what you try! 
-2

blabla gần như có thể được coi là thành viên riêng tư của Foo.

Xem this bài viết từ Douglas Crockford.

0

Nếu bạn không sử dụng từ khóa var, "blabla" sẽ trở thành biến toàn cục. Tại các điểm khác trong mã nếu bạn cũng sử dụng blabla không có var, nó cũng sẽ là toàn cục và bạn có thể vô tình thay đổi các trường hợp blabla khác và đưa ra các lỗi không mong muốn trong mã của bạn. "var" đặt biến trong phạm vi hiện tại, vì vậy trong trường hợp trên, nó chỉ có thể truy cập vào Foo.

5

Trong ví dụ blabla của bạn là biến cục bộ, vì vậy nó sẽ biến mất khi hàm xây dựng kết thúc.

Nếu bạn khai báo hàm bên trong hàm tạo, sử dụng biến, thì biến sẽ là một phần của đóng cho hàm đó và tồn tại miễn là hàm (ví dụ như thường là đối tượng):

function Foo() { 
    this.bla = 1; 
    var blabla = 10; 

    this.getBlabla = function() { 
    alert(blabla); // still here 
    } 
} 
+1

Bạn có thể có nghĩa là biến tồn tại miễn là hàm *, hoặc đối tượng * chức năng * để phân biệt nó với đối tượng được xây dựng. –

+1

@amnotiam: Có, bạn đúng, đó là mô tả hơn. – Guffa

+0

vì vậy chỉ các biến sử dụng "điều này" bên trong một nhà thầu sẽ trở thành một thuộc tính của các trường hợp?"var blabla = 10" sẽ chỉ là thuộc tính cục bộ của Foo - nó sẽ vẫn tồn tại chỉ khi có phương thức "này" sử dụng nó? – Daniel

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