2016-12-18 11 views
5

Tôi đã đi du lịch sâu hơn vào thế giới JS và đi qua 3 cách khác nhau tôi có thể phát triển các giỏ frontend của một trang web:Nếu chỉ có một thể hiện của một đối tượng, tôi có nên sử dụng một hàm tạo không?

Constructor với hàm Prototype

var cart = function(){ 
    this.items = {} 
} 

cart.prototype.increaseItemQty = function(partNumber){ 
    if(this.items[partNumber]){ 
     this.items[partNumber].qty += 1; 
    } else { 
     this.items[partNumber] = { 
      qty : 1 
     }; 
    } 
} 

cart = new cart(); 

Methods Trong Constructor

var cart2 = function(){ 
    this.items = {}; 
    this.increaseItemQty = function (partNumber) { 
     if(this.items[partNumber]){ 
      this.items[partNumber].qty += 1; 
     } else { 
      this.items[partNumber] = { 
       qty : 1 
      }; 
     } 
    } 
} 

cart2 = new cart2(); 

Phương pháp Object

var cart3 = { 
    items : {}, 
    increaseItemQty : function(partNumber){ 
     if(this.items[partNumber]){ 
      this.items[partNumber].qty += 1; 
     } else { 
      this.items[partNumber] = { 
       qty : 1 
      }; 
     } 
    } 
}; 

Nếu tôi biết rằng chỉ có một trường hợp của giỏ hàng thì tôi có nên sử dụng phương pháp Object Method không? Có lý do nào mà tôi vẫn nên sử dụng một nhà xây dựng?

Trả lời

2

Bạn nên sử dụng hàm khởi tạo nếu bạn nghĩ rằng bạn cần khởi tạo giỏ hàng với một số giá trị mặc định hoặc thực hiện một số công cụ khởi tạo cần được thực hiện trước khi sử dụng toàn bộ đối tượng.

Mặt khác, có thể bạn đang thiếu Object.create. Bạn không cần chức năng xây dựng để thực hiện một chuỗi nguyên mẫu:

var A = { 
    doStuff() { 
     console.log("I did some stuff"); 
    } 
}; 

var B = Object.create(A); 
B.moreStuff = function() { 
    console.log("I did even more stuff"); 
}; 

// A new object where its prototype is B 
var someB = Object.create(B); 
b.doStuff(); // ...from A 
b.moreStuff(); // ...from B 
+0

Tại sao 'B.prototype = {...'? Điều đó sẽ không cung cấp cho 'b' bất kỳ phương thức nào mà không cần phải thực hiện' b.prototype.moreStuff() '. Bạn có thể gán các thuộc tính trong đối số thứ hai cho 'Object.create'. –

+0

@squint bạn có thể làm điều đó, nhưng bạn sẽ cần phải sử dụng các bộ mô tả thuộc tính, quá chi tiết cho các trường hợp đơn giản hơn. –

+0

Có, các bộ mô tả thuộc tính là tiết, nhưng theo cách này hay cách khác, bạn cần thay đổi cách bạn cung cấp 'moreStuff' để có thể thực hiện' b.moreStuff() 'thay vì' b.prototype.moreStuff() ' . –

1

Sự khác nhau giữa các trường hợp 1 và 2: trong trường hợp 1, bạn chỉ định phương pháp để tất cả các trường của cart lớp hoặc các lớp con của nó, trong trường hợp 2 chỉ các phiên bản của cart.

Sự khác biệt giữa các trường hợp 2 và 3: trong trường hợp 3, hơn nữa, bạn chỉ tạo một cá thể bằng cách sử dụng biểu thức khởi tạo đối tượng và gán một số phương thức làm thuộc tính của nó. Bây giờ, nếu trả lời câu hỏi của bạn, nếu bạn chỉ có một ví dụ, về mặt lý thuyết nó sẽ là đủ để bạn thêm phương thức làm thuộc tính của nó như trong trường hợp 3. Hoặc thậm chí viết các hàm kiểu thủ tục.

Nhưng về mặt tính mở rộng và khả năng sử dụng lại mã, cách tốt nhất là sử dụng các phương pháp bằng cách tạo các lớp . Các lớp trong javascript là tập hợp các đối tượng có cùng nguyên mẫu. Vì vậy, cách tốt nhất là thêm các phương thức làm đặc tính của đối tượng nguyên mẫu như trong trường hợp 1. Nếu bạn sẽ chỉ có một ví dụ - sẽ không có sự khác biệt với bạn. Nhưng kể từ khi cart nên được khá nặng và phức tạp lớp, bất cứ khi nào yêu cầu để thay đổi giỏ hàng của bạn, trường hợp 1 sẽ là thuận tiện nhất.

+0

Tôi rất thích sử dụng các lớp học, nhưng điều này sẽ phải làm việc trong trình duyệt web của IE và Android. –

+0

@ JaredDunham Tôi có nghĩa là không sử dụng ES6 'class' từ. Tôi có nghĩa là các lớp như các đối tượng có cùng giá trị của thuộc tính 'prototype'. Điều đó được hỗ trợ ở mọi nơi. Bạn nên xem xét một số [ví dụ về kế thừa nguyên mẫu trong js] (http://stackoverflow.com/questions/2064731/good-example-of-javascripts-prototype-based-inheritance) – pttsky

3

Có, lý do (nhỏ) bạn không nên sử dụng hàm tạo: trường hợp sẽ giữ tham chiếu đến hàm tạo thông qua instance.[[Prototype]].constructor và do đó sẽ không bị thu gom rác. Nó sẽ lãng phí bộ nhớ vô ích bởi vì bạn sẽ không nhanh chóng làm lại nó.

var cart = new function(){ /* ... */ }; 
 
console.log(cart.constructor); // Won't be garbage-collected

Nếu bạn thích một cách tiếp cận chức năng bạn vẫn có thể làm điều gì đó như sau. Bằng cách này bạn cũng có thể có các biến riêng.

var cart = function() { 
 
    // You can add private variables here 
 
    this.items = {}; 
 
    this.increaseItemQty = function(partNumber) { 
 
    if(this.items[partNumber]) { 
 
     this.items[partNumber].qty += 1; 
 
    } else { 
 
     this.items[partNumber] = { 
 
     qty : 1 
 
     }; 
 
    } 
 
    }; 
 
    return this; 
 
}.call({}); 
 
cart.increaseItemQty(0); 
 
console.log(cart.items);

+1

IMHO, đó là một tối ưu hóa vi mô. –

1

Để tạo một đối tượng, về cơ bản nó có thể được tạo ra bằng cách sử dụng constructor 'chức năng' hay đơn giản với các ký hiệu đối tượng '{}' mà cả hai đều chính xác làm như vậy trong trường hợp của bạn ở trên .

Lợi thế chính với mẫu hàm tạo là, nó sẽ hữu ích hơn nếu bạn cần xử lý các đối số khi bạn tạo một cá thể như dưới đây.

function Car(model) { 
    this.model = model; 
} 

Hoặc nếu bạn cần sử dụng biến và phương thức riêng tư như dưới đây.

function Car() { 
    // private variable 
    var modelYear = 1990; 
    // private method 
    var isEligibleToInsurance = function() { 
     return this.modelYear > modelYear; 
    }; 

    this.isLatestModel = function() { 
     return isEligibleToInsurance(); 
    }; 
} 

Bằng cách này bạn có thể có phương pháp riêng và sử dụng cùng phương thức công khai. Khi bạn sử dụng ký hiệu đối tượng, bạn không thể có một phương thức riêng được sử dụng trên tất cả các phương thức công cộng và khi bạn sử dụng 'prototype', bạn không thể sử dụng các phương thức riêng được khai báo bên trong hàm tạo.

Lưu ý: Khi đặt tên cho lớp, bạn có thể làm theo trường hợp pascal để đặt tên là "Ô tô" thay vì "ô tô" và tạo cá thể với trường hợp lạc đà là "var car = new Car();"

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