Những gì bạn đang làm trong ví dụ của bạn không phải là mô hình "lớp" mà mọi người nghĩ đến trong JS - thường mọi người đang nghĩ đến mô hình lớp "bình thường" của Java/C#/C++/v.v. giả mạo với thư viện.
Thay vào đó ví dụ của bạn thực sự là khá bình thường và thiết kế JS tốt, nhưng cho đầy đủ tôi sẽ thảo luận về sự khác biệt hành vi bạn sẽ thấy giữa "thành viên" tư nhân và công cộng bạn có
var private = "a private variable";
this.public = "a public variable";
Truy cập private
từ bên trong bất kỳ chức năng nào của bạn sẽ nhanh hơn rất nhiều so với việc truy cập public
vì vị trí của private
có thể được xác định khá tốt chỉ với một tra cứu tĩnh của công cụ JS. Nỗ lực truy cập public
yêu cầu tìm kiếm, các công cụ JS hiện đại nhất thực hiện mức độ tra cứu bộ nhớ đệm, nhưng nó vẫn đắt hơn một truy cập var phức tạp đơn giản.
var privatefn = function() { ... };
this.publicfn = function() { ... };
Các quy tắc tra cứu tương tự áp dụng cho các chức năng như với biến trên truy cập, sự khác biệt duy nhất thực sự (trong ví dụ của bạn) là nếu chức năng của bạn được gọi là, nói privatefn()
vs this.publicfn()
, privatefn
sẽ luôn nhận được sự toàn cầu đối tượng cho this
. Nhưng cũng nếu có ai đó làm
f = foo.publicfn;
f();
Sau đó, các cuộc gọi đến f
sẽ có đối tượng toàn cầu như this
nhưng nó sẽ có thể thay đổi biến private
.
Cách thông thường hơn để thực hiện các chức năng công cộng (giải quyết chức năng công cộng tách biệt sửa đổi vấn đề thành viên riêng) là đặt các chức năng công khai trên mẫu thử nghiệm, ví dụ:
Foo.prototype.publicfn = function() { ... }
nào buộc các chức năng công cộng để không sửa đổi thông tin cá nhân - có một số lần, nơi đây không phải là một lựa chọn, nhưng đó là thực hành tốt vì nó cũng làm giảm sử dụng bộ nhớ một chút, thực hiện:
function Foo1() {
this.f = function(){ return "foo" };
}
vs
function Foo2() {
}
Foo2.prototype.f = function(){ return "foo" };
trong Foo1
bạn có một bản sao của đối tượng chức năng cho mỗi thể hiện của Foo1
(không phải tất cả các emory, chỉ cần đối tượng, ví dụ. new Foo1().f !== new Foo2().f
) trong khi ở Foo2
chỉ có một đối tượng hàm duy nhất.
dụ FooClass của bạn không đúng. Các ngữ nghĩa mới có hiệu quả: "var foo = {}; foo .__ proto__ = FooClass.prototype; var temp = FooClass.call (tạm thời); if (IsObject (temp)) foo = temp;". Điều này có nghĩa trong ví dụ foo của bạn sẽ là đối tượng mới "{reallypublicfn: function() {...}}" vì vậy nó sẽ không có nguyên mẫu FooClass hoặc hàm publicfn – olliej