2008-08-09 27 views
16

Có một vài cách để có được hành vi tầm cỡ như thế nào trong javascript, phổ biến nhất dường như là nguyên mẫu dựa như thế này:Bạn sử dụng kiểu nào để tạo "lớp"?

function Vector(x, y, x) { 
    this.x = x; 
    this.y = y; 
    this.z = z; 
    return this; 
} 

Vector.prototype.length = function() { return Math.sqrt(this.x * this.x ...); } 

và cách tiếp cận đóng cửa căn cứ tương tự như

function Vector(x, y, z) { 
    this.length = function() { return Math.sqrt(x * x + ...); } 
} 

Vì những lý do khác nhau sau này là nhanh hơn, nhưng tôi đã nhìn thấy (và tôi thường xuyên viết) phiên bản nguyên mẫu và tò mò như những gì người khác làm.

+0

Các thử nghiệm của tôi đã chỉ ra rằng cách tiếp cận dựa trên đóng cửa chậm hơn. Bạn phải nhanh chóng đóng cửa riêng biệt cho từng đối tượng. Cách tiếp cận nguyên mẫu chia sẻ các phương thức với tất cả các trường hợp. –

Trả lời

9

Việc gán chức năng cho mẫu thử nghiệm tốt hơn (đối với phương thức công khai) vì tất cả các phiên bản của lớp sẽ chia sẻ cùng một bản sao của phương thức. Nếu bạn gán hàm bên trong hàm tạo như trong ví dụ thứ hai, mỗi lần bạn tạo một cá thể mới, hàm tạo tạo một bản sao mới của hàm chiều dài và gán nó cho chỉ một cá thể đó.

Tuy nhiên, kỹ thuật thứ hai này hữu ích nếu bạn muốn mỗi bản sao có bản sao riêng, sử dụng chính là làm các phương thức riêng tư/đặc quyền có quyền truy cập vào biến riêng được khai báo bên trong hàm tạo và kế thừa cơ chế.

Douglas Crockford có tốt summary.

2

Vâng, tôi thực sự không có ý kiến ​​chuyên gia về vấn đề này. Tôi thường kết thúc bằng cách sử dụng cách tiếp cận dựa trên đóng cửa chỉ vì nó giữ mã đơn giản hơn để quản lý. Nhưng, tôi đã tìm thấy bản thân mình bằng cách sử dụng nguyên mẫu cho các phương pháp có tải dòng mã.

2

Bạn cũng có thể lựa chọn:

function Vector(x, y, z) { 
    function length() { 
    return Math.sqrt(x * x + ...); 
    } 
} 

Mà có lẽ cũng giống như chậm như ví dụ hai, nhưng nó trông giống như Java/C# và là một chút rõ ràng hơn.

3

May mắn thay tôi có thể sử dụng prototype.js, cung cấp một số trình bao bọc đẹp. Vì vậy, bạn có thể làm điều này:

var Person = Class.create({ 
    initialize: function(name) { 
     this.name = name; 
    }, 
    say: function(message) { 
     return this.name + ': ' + message; 
    } 
}); 

Prototype.js Documentation: Defining classes and inheritance

+0

Tôi không nghĩ rằng OP đã yêu cầu một wrapper che giấu các chi tiết. Anh ta muốn biết tại sao bạn lại chọn cách tiếp cận, vì vậy anh ta có thể cân nhắc những lợi ích –

4

Ngoài ra còn có phương pháp tiếp cận theo nghĩa đen đối tượng nguyên mẫu:

var Vector = function(){}; 

Vector.prototype = { 
    init:function(x,y,z) { 
    this.x = x; 
    this.y = y; 
    this.z = z; 
    }, 
    length:function() { 
    return Math.sqrt(x * x + ...); 
    } 
}; 

var v1 = new Vector(); 
v1.init(1,2,3); 
+0

Bạn không thể thiết lập đối tượng nguyên mẫu theo nghĩa đen nếu bạn kế thừa từ cái gì khác, điều đó sẽ ghi đè nguyên mẫu trước đó –

+0

Bạn đúng - nhưng trong trường hợp này, "Vector" là một đối tượng mới, vì vậy tôi không thấy cần phải lo lắng về các vấn đề thừa kế – JayTee

1

Tôi là một fan hâm mộ lớn của việc sử dụng John Resig's library cho việc này. Nhẹ, thẳng về phía trước, và bạn đã biết cách sử dụng nó nếu bạn quen thuộc với phong cách hướng đối tượng 'bình thường'.

1

Không có lớp nào trong javascript.

Tuy nhiên, có các đối tượng. Bạn không cần một lớp để tạo một đối tượng trong javascript.Nó có chức năng constuctor mà bạn có thể gọi với mới ví dụ:

var james = new Person(); 

Bạn có thể mô phỏng lớp như hành vi với:

nguyên mẫu Ví dụ:

function Car (type) { 
    this.type = type; 
    this.color = "red"; 
} 

Car.prototype.getInfo = function() { 
    return this.color + ' ' + this.type + ' car'; 
}; 

đối tượng dụ đen

var car = { 
    type: "honda", 
    color: "red", 
    getInfo: function() { 
     return this.color + ' ' + this.type + ' car'; 
    } 
} 
Các vấn đề liên quan