2012-05-26 35 views
9

Tôi đang cố gắng tìm ra cách xây dựng các lớp Javascript (hoặc các đối tượng đơn lẻ) một cách chính xác.Cách chính xác để tạo lớp Javascript là gì?

var obj = new Object(); 
obj.foo = 'bar'; 
obj.method = function() { ...} 

var obj = { 
    foo : 'bar', 
    method : function() { ...} 
} 

var obj = function(){} 
obj.prototype = { 
    foo : 'bar', 
    method: function() { ... } 
} 

Tôi muốn có thể đặt một vài thuộc tính và chỉ định phương thức khả dụng. Tôi cũng muốn có thể sử dụng những thứ như mixins trên các đối tượng để tôi có thể mở rộng các đối tượng này với những thứ như events.

+5

Quy tắC# 1: Không bao giờ sử dụng 'đối tượng mới()'. – Ryan

+0

@minitech, bạn chắc chứ? Họ chắc đã làm nó vì một lý do nào đó. – Xeoncross

+0

@ Xeoncross: Không phải là tôi biết. :-) –

Trả lời

8

Tôi đang cố gắng tìm ra cách xây dựng các lớp Javascript (hoặc đối tượng đơn lẻ) chính xác.

Có sự khác biệt lớn giữa những thứ đó ("các lớp" và đối tượng đơn lẻ). Hai ví dụ đầu tiên của bạn là các đối tượng một lần (single). Ví dụ thứ ba (cuối cùng) của bạn tạo hàm hàm khởi tạo sẽ cho phép bạn tạo nhiều đối tượng chia sẻ cùng một mẫu thử nghiệm. Tôi muốn giới thiệu làm tăng các prototype tài sản trên hàm xây dựng chứ không phải là thay thế nó như bạn đang làm, ví dụ:

var Thingy = function() { // Or use a function declaration rather than expression 
    // Optional initialization code here 
}; 
Thingy.prototype.foo = 'bar'; 
Thingy.prototype.method = function() { 
    // Method code here 
}; 

(. Chức năng Constructor, theo quy ước, bắt đầu với một chữ hoa)

Bạn sử dụng (chức năng singleton hoặc hàm dựng) phụ thuộc vào những gì bạn cần.

Kể từ ES2015 (còn gọi là "ES6"), nó đơn giản hơn, mặc dù không có cú pháp mới để xác định thuộc tính mẫu không phương thức (số foo) của bạn; có lẽ sẽ ở ES2017 hay ES2018, một khi this proposal di chuyển về phía trước, nhưng cho đến lúc đó:

class Thingy { 
    constructor() { 
     // Optional initialization code here 
    } 
    method() { 
    // Method code here 
    } 
} 
Thingy.prototype.foo = 'bar'; 

Nếu bạn cần phải nhận được vào phân cấp thừa kế, trong cú pháp ES5 cũ có một chút công bằng của hệ thống ống nước tham gia:

var Base = function() { 
}; 
Base.prototype.method = function(arg1) { 
    // ... 
}; 

var Derived = function() { 
    Base.call(this); 
}; 
Derived.prototype = Object.create(Base.prototype); 
Derived.prototype.constructor = Derived; 
Derived.prototype.method = function(arg1) { 
    // Using Base's `method`, if desired, is a bit ugly: 
    Base.prototype.method.call(this, arg1); 
}; 

... đó là lý do bạn sử dụng để xem thư viện tham gia, chẳng hạn như công cụ Class của Prototype hoặc Lineage của riêng tôi; những người đang lỗi thời bởi cú pháp ES2015, tuy nhiên, whcih làm cho nó hết sức đơn giản:

class Base { 
    method(arg1) { 
     // ... 
    } 
} 
class Derived extends Base { 
    method(arg1) { 
     // Use's the superclass's `method`, if desired, is easy: 
     super.method(arg1); 
    } 
} 

Re tiêu đề câu hỏi của bạn:

cách chính xác để tạo ra một lớp Javascript là gì?

Có một số cách chính xác để tạo "lớp" đối tượng trong JavaScript, vì JavaScript là một ngôn ngữ rất linh hoạt. Có các hàm xây dựng tiêu chuẩn, hàm "builder", Object.create (trong môi trường hỗ trợ ES5) cho phép bạn thực hiện nhiều thừa kế nguyên mẫu trực tiếp hơn và một số hàm khác. Một trong những điều tuyệt vời về JavaScript là bạn có thể chọn kiểu "lớp" của mình.

1

bạn cũng có thể sử dụng một cái gì đó như:

function O(x,y) { 
    this.x=x; 
    this.y=y; 
    this.method=function() {...} 
    return this; 
} 

var o=new O(0,0); 
0

Nếu bạn đang nhắm mục tiêu một trình duyệt hoặc môi trường có hỗ trợ ES5, sau đó bạn có thể làm điều này:

var Person = { 
    foo: ..., 
    bar: ... 
}; 

var Mike = Object.create(Person, { baz: ... }); 
1

Nếu bạn đang tìm kiếm một giải pháp thực tế hơn là một giải pháp lý thuyết, bạn nên sử dụng một khung công tác tốt hơn.

  • Backbone.js có tất cả những gì bạn cần, bao gồm mixin và hệ thống sự kiện.

Nếu bạn cần một số vật dụng quá, hãy xem xét

Cả hai đều cung cấp một kiến ​​trúc sạch và có thể được sử dụng mà không widget, nhưng họ đòi hỏi một chút học tập nhiều hơn Backbone.

Cấu trúc thừa kế mà các khung công tác này cung cấp rất giống với khung công tác thông thường (Java). Đó là bởi vì họ tạo ra các đối tượng đặc biệt trong nội bộ mà chỉ phục vụ như là prototype s cho những người khác, và do đó đảm nhận vai trò của các lớp.

Ví dụ: khi bạn gọi Ext.define('MyClass', {extend: 'ParentClass', mixins: foo, ... }), thì Ext sẽ tạo một function "MyClass" và đối tượng ẩn danh (MyClass.prototype) chứa các phương pháp bạn đã cung cấp.

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