2012-11-23 28 views
48

Giả sử tôi có một đối tượng FooJavascript thêm phương pháp để phản đối

Làm thế nào tôi có thể mở rộng đối tượng này bằng cách thêm một phương pháp bar() và cũng đảm bảo rằng trường hợp tương lai của Foo có phương pháp này?

Trả lời

42

bạn cần phải thêm nó vào nguyên mẫu của Foo:

function Foo(){} 
Foo.prototype.bar = function(){} 
var x = new Foo() 
x.bar() 
10

Có nhiều cách để tạo các đối tượng có thể sử dụng lại như thế này trong JavaScript. Mozilla có một giới thiệu tốt đẹp ở đây:

Sau đây sẽ làm việc trong ví dụ của bạn:

function Foo(){ 
    this.bar = function(){ 
     alert("Hello World!"); 
    } 
} 

myFoo = new Foo(); 
myFoo.bar(); // Hello World​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​ 
5

Bạn có thể biến thanh thành một hàm làm cho nó thành một phương thức.

Foo.bar = function(passvariable){ }; 

Là một tài sản nó chỉ sẽ được chỉ định một chuỗi, kiểu dữ liệu hoặc boolean

Foo.bar = "a place"; 
39

này tất cả phụ thuộc vào cách bạn đang tạo Foo, và làm thế nào bạn có ý định sử dụng .bar().

Trước tiên, bạn có đang sử dụng hàm tạo hàm cho đối tượng của mình không?

var myFoo = new Foo(); 

Nếu vậy, sau đó bạn có thể mở rộng tài sản prototype các Foo chức năng với .bar, như vậy:

function Foo() { /*...*/ } 
Foo.prototype.bar = function() { /*...*/ }; 

var myFoo = new Foo(); 
myFoo.bar(); 

chạy theo mốt này, mỗi thể hiện của Foo bây giờ có quyền truy cập vào các CÙNG bản sao của .bar.
Để wit: .bar sẽ có quyền truy cập ĐẦY ĐỦ để this, nhưng sẽ có hoàn toàn không có quyền truy cập-variables bên trong hàm constructor:

function Foo() { var secret = 38; this.name = "Bob"; } 
Foo.prototype.bar = function() { console.log(secret); }; 
Foo.prototype.otherFunc = function() { console.log(this.name); }; 

var myFoo = new Foo(); 
myFoo.otherFunc(); // "Bob"; 
myFoo.bar(); // error -- `secret` is undefined... 
      // ...or a value of `secret` in a higher/global scope 

Bằng cách khác, bạn có thể định nghĩa một chức năng để trả lại bất kỳ đối tượng (không this), với .bar tạo ra như là một tài sản của đối tượng đó:

function giveMeObj() { 
    var private = 42, 
     privateBar = function() { console.log(private); }, 
     public_interface = { 
      bar : privateBar 
     }; 

    return public_interface; 
} 

var myObj = giveMeObj(); 
myObj.bar(); // 42 

chạy theo mốt này, bạn có một hàm tạo đối tượng mới.
Mỗi đối tượng trong số đó có chức năng .bar được tạo cho chúng.
Mỗi chức năng .bar có quyền truy cập, thông qua những gì được gọi là đóng, cho các biến "riêng tư" trong hàm trả về đối tượng cụ thể của chúng.
Mỗi .bar vẫn có quyền truy cập vào this là tốt, như this, khi bạn gọi hàm như myObj.bar(); sẽ luôn luôn tham khảo myObj (public_interface, trong ví dụ của tôi Foo).

Nhược điểm của định dạng này là nếu bạn định tạo hàng triệu đối tượng này, đó cũng là hàng triệu bản sao của .bar, sẽ ăn vào bộ nhớ.

Bạn cũng có thể thực hiện điều này bên trong hàm khởi tạo, đặt this.bar = function() {}; bên trong hàm dựng - một lần nữa, ngược lại sẽ là truy cập đóng vào biến riêng tư trong hàm tạo và nhược điểm.

Vì vậy, câu hỏi đầu tiên là:
Bạn có mong đợi phương pháp của bạn để có quyền truy cập để đọc/sửa đổi dữ liệu "riêng", mà không thể được truy cập thông qua các đối tượng chính nó (thông qua this hoặc myObj.X)?

và câu hỏi thứ hai là: Bạn có tạo ra đủ các đối tượng này để bộ nhớ có trở ngại lớn không, nếu bạn cung cấp cho họ từng chức năng cá nhân của riêng mình thay vì cho họ chia sẻ?

Ví dụ, nếu bạn đã từng tam giác và mỗi kết cấu riêng .draw chức năng của chúng trong một trò chơi 3D cao cấp, đó có thể là quá mức cần thiết, và nó có khả năng sẽ ảnh hưởng đến tốc độ khung hình trong một hệ thống tinh tế như vậy ...

Tuy nhiên, nếu bạn muốn tạo 5 thanh cuộn trên mỗi trang và muốn mỗi vị trí có thể thiết lập vị trí của nó và theo dõi xem nó có bị kéo hay không, không cho phép mọi ứng dụng khác có quyền truy cập để đọc/đặt những thứ tương tự , sau đó thực sự không có lý do gì để lo sợ rằng 5 chức năng bổ sung sẽ giết ứng dụng của bạn, giả sử rằng nó có thể dài 10.000 dòng (hoặc nhiều hơn).

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