Nó làm 5 việc:
- Nó tạo ra một đối tượng mới. Loại đối tượng này chỉ đơn giản là đối tượng .
- Nó đặt thuộc tính bên trong, không thể truy cập, [[nguyên mẫu]] (tức là __proto__ ) của đối tượng mới này thành đối tượng nguyên mẫu bên ngoài, có thể truy cập, của hàm tạo (mọi đối tượng hàm tự động có thuộc tính nguyên mẫu ).
- Nó làm cho
this
điểm biến đến đối tượng mới được tạo.
- Nó thực thi hàm constructor, sử dụng đối tượng vừa tạo bất cứ khi nào
this
được đề cập.
- Nó trả về đối tượng vừa tạo, trừ khi hàm constructor trả về
null
tham chiếu không đối tượng. Trong trường hợp này, tham chiếu đối tượng đó được trả về thay thế.
Lưu ý: hàm constructor đề cập đến hàm sau new
từ khóa, như trong
new ConstructorFunction(arg1, arg2)
Khi điều này được thực hiện, nếu một thuộc tính không xác định của đối tượng mới được yêu cầu, tập lệnh sẽ kiểm tra đối tượng [[nguyên mẫu]] của đối tượng cho thuộc tính thay thế. Đây là cách bạn có thể nhận được một cái gì đó tương tự như kế thừa lớp truyền thống trong JavaScript.
Phần khó nhất về điều này là điểm số 2. Mọi đối tượng (bao gồm các hàm) đều có thuộc tính bên trong này được gọi là [[nguyên mẫu]] . Nó chỉ có thể được đặt tại thời điểm tạo đối tượng, với new , với Object.create hoặc dựa trên chữ (các hàm mặc định là Function.prototype, các số thành Number.prototype, v.v.). Nó chỉ có thể được đọc với Object.getPrototypeOf (someObject) . Không có cách nào khác để đặt hoặc đọc giá trị này.
Các hàm, ngoài thuộc tính [[nguyên mẫu]] , còn có một thuộc tính được gọi là nguyên mẫu và đó là thứ mà bạn có thể truy cập và sửa đổi, để cung cấp các thuộc tính và phương thức được kế thừa cho các đối tượng bạn tạo.
Đây là một ví dụ:
ObjMaker = function() {this.a = 'first';};
// ObjMaker is just a function, there's nothing special about it that makes
// it a constructor.
ObjMaker.prototype.b = 'second';
// like all functions, ObjMaker has an accessible prototype property that
// we can alter. I just added a property called 'b' to it. Like
// all objects, ObjMaker also has an inaccessible [[prototype]] property
// that we can't do anything with
obj1 = new ObjMaker();
// 3 things just happened.
// A new, empty object was created called obj1. At first obj1 was the same
// as {}. The [[prototype]] property of obj1 was then set to the current
// object value of the ObjMaker.prototype (if ObjMaker.prototype is later
// assigned a new object value, obj1's [[prototype]] will not change, but you
// can alter the properties of ObjMaker.prototype to add to both the
// prototype and [[prototype]]). The ObjMaker function was executed, with
// obj1 in place of this... so obj1.a was set to 'first'.
obj1.a;
// returns 'first'
obj1.b;
// obj1 doesn't have a property called 'b', so JavaScript checks
// its [[prototype]]. Its [[prototype]] is the same as ObjMaker.prototype
// ObjMaker.prototype has a property called 'b' with value 'second'
// returns 'second'
Nó giống như kế thừa lớp bởi vì bây giờ, bất kỳ đối tượng nào bạn thực hiện new ObjMaker()
cũng sẽ xuất hiện để kế thừa thuộc tính 'b'.
Nếu bạn muốn một cái gì đó giống như một lớp con, thì bạn làm điều này:
SubObjMaker = function () {};
SubObjMaker.prototype = new ObjMaker(); // note: this pattern is deprecated!
// Because we used 'new', the [[prototype]] property of SubObjMaker.prototype
// is now set to the object value of ObjMaker.prototype.
// The modern way to do this is with Object.create(), which was added in ECMAScript 5:
// SubObjMaker.prototype = Object.create(ObjMaker.prototype);
SubObjMaker.prototype.c = 'third';
obj2 = new SubObjMaker();
// [[prototype]] property of obj2 is now set to SubObjMaker.prototype
// Remember that the [[prototype]] property of SubObjMaker.prototype
// is ObjMaker.prototype. So now obj2 has a prototype chain!
// obj2 ---> SubObjMaker.prototype ---> ObjMaker.prototype
obj2.c;
// returns 'third', from SubObjMaker.prototype
obj2.b;
// returns 'second', from ObjMaker.prototype
obj2.a;
// returns 'first', from SubObjMaker.prototype, because SubObjMaker.prototype
// was created with the ObjMaker function, which assigned a for us
Tôi đã đọc rất nhiều rác về chủ đề này trước khi cuối cùng tìm thấy trang này , nơi điều này được giải thích rất tốt với các sơ đồ đẹp.