Tôi đã đọc về cách tài sản nguyên mẫu Javascript hoạt động cùng với thừa kế và sau đó bắt đầu xem xét thông qua mã Angular.js và đưa ra một số câu hỏi.Tại sao chỉ định Cái gì đó cho Something.prototype.constructor?
Trước hết, tôi đọc rằng thuộc tính mẫu thử trỏ đến một đối tượng có thuộc tính "hàm tạo" trỏ trở lại hàm ban đầu được sử dụng để tạo đối tượng. Vì vậy, ví dụ:
// This is the constructor
function Shape() {
this.position = 1;
}
// The constructor points back to the original function we defined
Shape.protoype.constructor == Shape;
Nguyên mẫu cũng chứa bất kỳ các phương pháp khác hoặc tài sản đã được xác định trên nó bằng cách cho chúng tôi hoặc bằng ngôn ngữ Javascript chính nó, và đây là những chia sẻ của tất cả các trường của đối tượng. Nếu bạn muốn một đối tượng được gọi là Square để kế thừa từ Shape, bạn cần phải đặt mẫu thử Square bằng một mẫu mới của Shape vì thuộc tính [[prototype]] bên trong của Square.prototype được đặt thành giá trị đối tượng công khai của thuộc tính Shape.prototype .
function Square() {}
Square.prototype = new Shape();
var square = new Square();
square.position; // This will output 1
Điều này có ý nghĩa với tôi.
Tuy nhiên, mã Angular.js mà tôi có câu hỏi về dường như có liên quan đến tất cả những điều này nhưng làm điều gì đó mà tôi không hiểu. Nó dường như không phải là đối phó với thừa kế vì vậy tôi có thể hiểu tại sao sẽ có sự khác biệt, nhưng tôi chỉ tò mò tại sao họ đã viết nó theo cách họ đã làm.
Trong phạm vi Angular.js, có một đối tượng HashMap và đối tượng Lexer, nhưng chúng được định nghĩa khác nhau nhưng có vẻ như được khởi tạo và sử dụng theo cùng một cách chính xác. Hàm tạo của Lexer được định nghĩa lần đầu tiên, và sau đó chúng đặt nguyên mẫu cho một đối tượng chứa các phương thức có thể được chia sẻ bởi tất cả các trường hợp của Lexer. Điều này tất cả đều có ý nghĩa. Những gì tôi không hiểu là lý do tại sao họ chỉ định thuộc tính "constructor" và thiết lập nó chỉ là "Lexer" khi chúng không cho HashMap bên dưới.
var Lexer = function(options) {
this.options = options;
};
// Notice they specify Lexer as the constructor even though they don't for HashMap below
Lexer.prototype = {
constructor: Lexer,
lex: function(text) { ... },
is: function(ch, chars) { ... },
peek: function(i) { ... },
isNumber: function(ch) { ... },
isWhitespace: function(ch) { ... },
isIdent: function(ch) { ... },
isExpOperator: function(ch) { ... },
throwError: function(error, start, end) { ... },
readNumber: function() { ... },
readIdent: function() { ... },
readString: function(quote) { ... }
};
Sau đó, nếu bạn nhìn vào mã HashMap, chúng thực hiện tương tự ngoại trừ việc chúng không chỉ định thuộc tính hàm tạo. Tại sao điều này? Nó xuất hiện để làm việc chính xác như nhau, và tôi đã thử nghiệm rằng các nhà xây dựng vẫn được gọi.
// The HashMap Constructor
function HashMap(array, isolatedUid) {
if (isolatedUid) {
var uid = 0;
this.nextUid = function() {
return ++uid;
};
}
forEach(array, this.put, this);
}
HashMap.prototype = {
put: function(key, value) { ... },
get: function(key) { ... },
remove: function(key) { ... }
};
Vì vậy, thuộc tính hàm tạo tùy chọn khi không có kế thừa, vì vậy có thể một người đã viết Lexer và một HashMap khác và một người đã quyết định chỉ định hàm tạo?
xem thêm [Xác định nguyên mẫu Javascript] (http://stackoverflow.com/q/17474390/1048572) – Bergi
@Bergi Cảm ơn, điều đó giúp ích. – Triad