2013-08-14 31 views
6

Thông thường tôi sử dụng phương pháp OOP chuẩn dựa trên nguyên mẫu và lớp học của tôi trông như thế nàylớp khai báo bên trong đóng cửa vs lớp chuẩn mà không đóng cửa

var std = function(){ 
    this.log = function(msg){ console.log("want to be private. " + msg) }; 
}; 

std.prototype = { 
    logInfo: function(msg){ 
     this.log(msg); 
    } 
}; 

nhưng trong trường hợp đó log là phương pháp nào và bất cứ ai có thể sử dụng nó. Nhưng tôi muốn làm cho nó riêng tư, nhưng vẫn có sẵn trong các phương pháp được khai báo trong nguyên mẫu. Vì điều đó, chúng tôi sẽ cần đóng cửa. Mã sẽ thay đổi cho câu hỏi này

var closureStd = (function(){ 
var std = function(){}; 
var log = function(msg){ console.log("I'm really private, youhooo!" + msg) }; 

std.prototype = { 
    logInfo: function(msg){ 
     log(msg); 
    } 
}; 

return std; 
})(); 

Vì vậy tôi: sự khác biệt giữa stdclosureStd và là những gì những gì là giá Tôi cần phải trả tiền để có thể gọi các phương thức tư nhân từ nguyên mẫu?

+1

liên kết hữu ích cho bạn: [Chi phí của sự riêng tư] (http://blog.jcoglan.com/2012/01/19/the-cost-of- privacy /) và [Mô-đun mô-đun Javascript] (http://briancray.com/posts/javascript-module-pattern) –

+0

Cảm ơn bài viết thú vị. Nó nhận được của tôi một số điểm, nhưng không trả lời câu hỏi ( – Ph0en1x

+0

Xin lỗi, không thông báo rằng bạn thêm bài viết thứ 2. Cần phải đọc nó cũng có. – Ph0en1x

Trả lời

2

sự khác biệt giữa std và closureStd là gì?

Phương thức khởi tạo std tạo phương thức mới cho mọi yêu cầu trong khi closureStd thì không. Bạn nên đã thực hiện nó

function std(){} 
std.prototype = { 
    log: function(msg){ console.log("want to be private. " + msg) }, 
    logInfo: function(msg){ this.log(msg); } 
}; 

Và, tất nhiên (bạn đã biết) các log chức năng trong closureStd được lưu trữ trong một biến (tư nhân) trong khi trên std dụ nó có thể truy cập (và ghi đè lên) từ bên ngoài vào mỗi trường hợp (hoặc trên nguyên mẫu của chúng). Trong kết thúc, nó là một biến tra trong chuỗi phạm vi (có thể giả định tĩnh), trong khi đối với phương thức đó là tra cứu tài sản trên một đối tượng (và chuỗi nguyên mẫu của nó), có thể động nhưng được tối ưu hóa bằng nhau trong các công cụ hiện đại.

giá mà tôi cần trả để có thể gọi phương thức riêng tư từ nguyên mẫu là gì?

Không có. Mô hình mô-đun là phổ biến và giá rẻ, tra cứu biến trong một chuỗi tĩnh rất nhanh. Tôi muốn lo lắng về bộ nhớ vì bạn đang tạo ra rất nhiều trường hợp phương thức trong phương thức khởi tạo.

1

Tôi cũng đã thực hiện một số tests để đo lường hiệu suất (kết quả sẽ nằm trong bảng điều khiển) và tôi thấy rằng việc đưa lớp vào đóng cửa thể hiện hiệu suất tốt hơn so với phương pháp đặt trong hàm tạo. Bạn cũng có các tùy chọn kế thừa. Vì vậy, bây giờ tôi không thấy bất lợi và sẽ luôn luôn sử dụng lớp bên trong đóng cửa khi tôi sẽ cần phương pháp riêng.

1

Lưu ý rằng mẫu mô-đun được cung cấp bởi link Bondye được cung cấp không giữ thuộc tính riêng dụ. Nó hoạt động tuyệt vời cho các thuộc tính chức năng kể từ khi chức năng sẽ không thay đổi cho từng trường hợp nhưng làm việc một chút khó lường đối với tài sản có giá trị như các mã sau minh họa:

var module = (function() { 
    // private variables and functions 
    var foo = 'bar'; 
    // constructor 
    var module = function (name) { 
     // instance variables 
     this.name=name; 
    }; 
    // prototype 
    module.prototype = { 
     constructor: module, 
     something: function() { 
      // notice we're not using this.foo 
      console.log("foo in "+this.name+" is:",foo); 
      foo="new value"; 
     } 
    }; 
    // return module 
    return module; 
})(); 

var m1 = new module("m1"); 
var m2 = new module("m2"); 
m1.something();// foo in m1 is: bar 
m1.something();// foo in m1 is: new value 
m2.something();// foo in m2 is: new value 

Như bạn có thể thấy trong dòng cuối cùng của mã cả m1 và m2 instance chia sẻ một biến riêng gọi là foo (tất cả các cá thể sẽ trỏ đến cùng một giá trị).

Những gì tôi có thể tạo ra từ other link mà Bondye đăng là khó mô phỏng tính riêng tư trong JavaScript và bạn có thể cân nhắc sử dụng quy ước đặt tên để chỉ ra thuộc tính là riêng tư.Bạn có thể sử dụng một cái gì đó như trình biên dịch đóng cửa google và chú thích mã JS của bạn để chỉ ra các cá nhân; nhưng bằng cách sử dụng trình biên dịch đóng cửa có nhược điểm riêng của nó (thư viện được sử dụng không thể được biên dịch trừ khi Compiler đóng cửa tương thích và mã phải ở định dạng nhất định để được biên dịch trong chế độ nâng cao).

Một tùy chọn khác là loại bỏ hoàn toàn nguyên mẫu (ít nhất là cho mọi thứ sử dụng thuộc tính riêng) và đặt mọi thứ vào nội dung hàm của hàm tạo (hoặc sử dụng hàm trả về đối tượng).

// function returning an object 

function makeObj(name){ 
    // private vars: 
    var foo = "bar"; 
    return { 
    name:name, 
    something:function(){ 
     console.log("foo in "+this.name+" is:",foo); 
     foo="new value"; 
    } 
    } 
} 
var m1=makeObj("m1"); 
var m2=makeObj("m2"); 
m1.something();// foo in m1 is: bar 
m1.something();// foo in m1 is: new value 
m2.something();// foo in m2 is: bar 

// constructor with everything in the constructor's body: 

function Obj(name){ 
    // private vars: 
    var foo = "bar"; 
    this.name=name; 
    this.something=function(){ 
    console.log("foo in "+this.name+" is:",foo); 
    foo="new value"; 
    } 
} 
Obj.prototype.someOtherFunction=function(){ 
    // anything here can't access the "private" variables 
} 
var m1=new Obj("m1"); 
var m2=new Obj("m2"); 
m1.something();// foo in m1 is: bar 
m1.something();// foo in m1 is: new value 
m2.something();// foo in m2 is: bar 

Một vấn đề nữa bạn có thể gặp phải khi sử dụng các giá trị cá thể riêng là chúng chỉ có thể truy cập trong ví dụ. Khi bạn muốn sao chép một đối tượng và định nghĩa một hàm nhân bản trong đối tượng của bạn để tạo một cá thể mới, bạn phải viết các hàm truy nhập công khai để đặt các giá trị riêng vì bạn không thể đặt chúng trực tiếp như trong Java private fields. Thông tin

Thông tin thêm về sử dụng các hàm constructor ở đây: Prototypical inheritance - writing up

+0

Cảm ơn câu trả lời của bạn. Ví dụ đầu tiên là rất intresting và phải mất một thời gian để Bây giờ tôi thấy rằng việc đóng cửa không phải là một biến thể hoàn hảo cho các lĩnh vực riêng tư, nhưng câu hỏi ban đầu là về các phương pháp. –

+0

@silent_coder Bạn là đúng, ví dụ đầu tiên là tốt cho các chức năng riêng tư, đó là mã từ liên kết được cung cấp bởi Bondye.Vì SO điểm cao trên google tôi nghĩ rằng nó là tốt để đề cập đến rằng các giá trị cá nhân không phải là dễ dàng. – HMR