2010-04-24 56 views
12

Có cách nào để gọi các hàm javascript "công khai" từ các hàm "riêng tư" trong một lớp không?Truy cập các phương thức "Công khai" từ các phương thức "Riêng tư" trong lớp javascript

Kiểm tra các lớp dưới đây:

function Class() 
{ 
    this.publicMethod = function() 
    { 
     alert("hello"); 
    } 

    privateMethod = function() 
    { 
     publicMethod(); 
    } 

    this.test = function() 
    { 
     privateMethod(); 
    } 
} 

Đây là mã tôi chạy:

var class = new Class(); 
class.test(); 

Firebug cho lỗi này:

publicMethod không được định nghĩa: [Phá vỡ về vấn đề này error] publicMethod();

Có cách nào khác để gọi publicMethod() trong privateMethod() mà không truy cập vào biến lớp toàn cầu [tức là class.publicMethod()]?

+4

Tôi hy vọng nó chỉ là lỗi chính tả trong ví dụ của bạn ở đây, nhưng 'privateMethod' của bạn là một biến toàn cục. –

+0

Trong Firefox nếu tôi gọi 'class.privateMethod()' có một lỗi trong khi 'class.publicMethod()' hoạt động tốt, do đó, có vẻ như có sự khác biệt giữa hai hàm. – mon4goos

Trả lời

5

Câu trả lời được chấp nhận có tác dụng phụ không mong muốn có thể là bản sao riêng của publicMethod, test, và privateMethod sẽ được tạo ra trong mỗi trường hợp. Các thành ngữ để tránh điều này là:

function Class() 
{} 

Class.prototype=(function() 
{ 
    var privateMethod = function(self) 
    { 
     self.publicMethod(); 
    } 


    return 
    { 
     publicMethod: function() 
     { 
      alert("hello"); 
     }, 
     test: function() 
     { 
      privateMethod(this); 
     } 
    }; 
}()); 

Nói cách khác, bạn cần phải vượt qua this đến chức năng riêng như một cuộc tranh cãi. Đổi lại, bạn nhận được đúng mẫu nguyên mẫu mà không phải gây ô nhiễm từng phiên bản với các phiên bản riêng của các chức năng riêng tư và công khai.

+2

Rất tuyệt! Thay vì truyền vào, bạn luôn có thể 'privateMethod.call (this)' – gnarf

8

Bạn có thể lưu biến trong phạm vi của hàm tạo để giữ tham chiếu đến this.

Xin lưu ý: Trong ví dụ của bạn, bạn để lại var trước khi privateMethod = function() làm cho rằng privateMethod toàn cầu. Tôi đã cập nhật giải pháp ở đây:

function Class() 
{ 
    // store this for later. 
    var self = this; 
    this.publicMethod = function() 
    { 
    alert("hello"); 
    } 

    var privateMethod = function() 
    { 
    // call the method on the version we saved in the constructor 
    self.publicMethod(); 
    } 

    this.test = function() 
    { 
    privateMethod(); 
    } 
} 
2

Câu trả lời của torazaburo là câu trả lời hay nhất, vì nó tránh tạo nhiều bản sao của các thành viên riêng tư. Tôi ngạc nhiên rằng Crockford không đề cập đến nó. Cách khác, tùy thuộc vào cú pháp bạn muốn khai báo chức năng thành viên công khai, bạn có thể thực hiện điều này:

function Class() 
{} 

(function() { 
    var privateMethod = function(self) { 
     self.publicMethod(); 
    }; 

    Class.prototype.publicMethod = function() { 
     alert('hello'); 
    }; 

    Class.prototype.test = function() { 
     privateMethod(this); 
    }; 
}()); 
0

Phương pháp này không phải là phương pháp được khuyến khích? Tôi không chắc chắn mặc dù

var klass = function(){ 
    var privateMethod = function(){ 
    this.publicMethod1(); 
    }.bind(this); 

    this.publicMethod1 = function(){ 
    console.log("public method called through private method"); 
    } 

    this.publicMethod2 = function(){ 
    privateMethod(); 
    } 
} 

var klassObj = new klass(); 
klassObj.publicMethod2(); 
Các vấn đề liên quan