2013-04-07 29 views
8

Giả sử bạn đang tạo kiểu dữ liệu và vạch trần hành vi của nó.Javascript: một số nguyên tắc về cách xác định loại dữ liệu mới là gì?

Bạn có thể đưa ra một số ví dụ về khi bạn sẽ sử dụng:

  • một hàm & mới:

    // define new data type 
    var CustomDataType= function(){ 
             this.a='whatever'; 
             this.doX= function(){/*some code*/}; 
            } 
    
    // create a new instance of our custom data type 
    var obj= new customDataType(); 
    
  • một đối tượng đen & Object.create:

    // define new data type 
    var customDataType = { 
             a: 'whatever', 
             doX: function(){/*some code*/} 
            } 
    
    // create a new instance of our custom data type 
    var obj= Object.create(customDataType); 
    
  • một chức năng giúp bạn xây dựng đối tượng r:

    function customDataTypeFactory(options){ 
        return { 
          a: 'whatever', 
          doX: function(){/*some code*/} 
         } 
    }; 
    
    // create a new instance of our custom data type 
    var obj= customDataTypeFactory(options); 
    

tôi cảm thấy điều này có thể được dán nhãn trùng lặp cho: new vs Object.create nhưng sự quan tâm chính của tôi không có trong thảo luận cái nào là tốt hơn nhưng thay vì biết nếu có những trường hợp sử dụng cụ thể mà người ta nên được ưa thích hơn những người khác.

Tôi đã đọc nhiều bài đăng về các câu hỏi liên quan và sách từ Crockford: Javascript: các phần hay. Cho đến nay tôi đã kết luận rằng đó là vấn đề ưu tiên, khó khăn từ lời khuyên của Crockford vang dội với tôi với tôi: "cố gắng tránh những tính năng nguy hiểm và không cần thiết" ... Tôi đang nói về new.

+0

Phiên bản đầu tiên và thứ ba của bạn đặt thuộc tính trực tiếp trên đối tượng mới. Trong phiên bản thứ hai của bạn, đối tượng thừa hưởng các thuộc tính. Tôi không biết rằng có bất kỳ câu trả lời cụ thể cho câu hỏi của bạn. Việc đầu tiên sử dụng một constructor nếu bạn gọi bằng cách sử dụng 'new', và' instanceof' sẽ làm việc để xác định đối tượng đó.Cái thứ ba không yêu cầu sử dụng 'new', nhưng' instanceof' sẽ không hữu dụng. Điều thứ hai một lần nữa thừa kế các thuộc tính, do đó, xây dựng một số đối tượng theo cách đó tất cả sẽ chia sẻ dữ liệu và tất cả các đối tượng sẽ quan sát các bản cập nhật cho đối tượng được kế thừa. –

+0

... và đừng quá hung hăng về cảnh báo nguy hiểm của Crockford. Tôi nghĩ anh ấy lo lắng quá nhiều. Ý tôi là, lấy tất cả vào, nhưng lấy nó bằng một hạt muối. –

+1

'this.doX =' nên là 'doX:' trong hai đoạn cuối –

Trả lời

7

Tôi sẽ bắt đầu với cách tôi thường xác định các lớp:

function CustomDataType(a) 
{ 
    this.a = a; 
    this.b = 2; 
} 
CustomDataType.prototype = { 
    doX : function() {} 
}; 
var obj = new CustomDataType(1); 

tôi gán biến trong các nhà xây dựng vì F.prototype = { a : [1,2,3]; } là có vấn đề, mảng sẽ được chia sẻ giữa các trường trừ khi tài sản được reinitialized trong constructor (có vấn đề đối với tất cả các kiểu không nguyên thủy). Và nó cũng cần thiết khi tài sản bằng cách nào đó phụ thuộc vào các đối số cho các nhà xây dựng. Tôi khai báo các phương thức trong nguyên mẫu để chúng được chia sẻ giữa tất cả các cá thể, nếu bạn sử dụng thừa kế nó có nghĩa là bạn có thể có các cuộc gọi siêu, nó cũng sẽ dẫn đến việc sử dụng bộ nhớ ít hơn vì phương pháp này chỉ được cấp phát một lần (t một vấn đề lớn).

Tôi chưa bao giờ sử dụng Object.create, tôi không thấy bất kỳ lý do gì để làm điều đó trừ khi bạn tham gia vào một số tin tặc năng động điên rồ.

Tôi sử dụng các đối tượng bất cứ khi nào cảm thấy không cần thiết để tạo một lớp riêng cho các đối tượng, ví dụ nếu đối số của nó là phương thức (vì vậy người gọi không cần phải rõ ràng), hoặc nếu đó là một số giá trị nội bộ không được truy cập bởi bất cứ ai khác.

Nhà máy của bạn về bản chất giống như đối tượng theo nghĩa đen. Tôi cho rằng nó có thể hữu ích nếu bạn cần tạo một số cấu trúc jsonesque và thiết lập một số giá trị mặc định.

Tôi không hiểu tại sao new sẽ nguy hiểm hoặc không cần thiết, trong bối cảnh nào anh ấy nói vậy?

Nhưng tôi nghĩ rằng rất nhiều trong số đó đi xuống để nếm thử. Hãy kiên định và không làm phức tạp mọi thứ.

+2

Vấn đề của Crockford với 'new' là:" * Nếu bạn quên bao gồm tiền tố 'new' khi gọi hàm hàm dựng, thì' this' sẽ Tuy nhiên, điều này sẽ bị ràng buộc với đối tượng toàn cầu, vì vậy thay vì tăng thêm đối tượng mới của bạn, bạn sẽ có các biến toàn cục. " – DCoder

+1

Ah, tôi nhớ đọc về điều đó, có lẽ từ anh ấy. Bạn có thể làm một cái gì đó như 'function C (x) {if (this == window) trả về C (x) mới; this.x = x; } ' Tôi xáo trộn rất nhiều khi tôi viết JS, nhưng tôi chưa bao giờ quên viết 'mới' ... –

+0

@AdamBergmark sẽ không tốt hơn nếu bạn ném lỗi để thực thi bằng cách sử dụng mới? – Dreamwalker

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