Tôi biết rất nhiều cách để tạo các đối tượng JS nhưng tôi không biết cách Object.create(null)đó.
Câu hỏi:
nó có giống hệt như:
var p = {}
đấu với
var p2 = Object.create(null);
?
Tôi biết rất nhiều cách để tạo các đối tượng JS nhưng tôi không biết cách Object.create(null)đó.
Câu hỏi:
nó có giống hệt như:
var p = {}
đấu với
var p2 = Object.create(null);
?
Câu trả lời:
Chúng không tương đương. {}.constructor.prototype == Object.prototypetrong khi Object.create(null)không thừa kế từ bất cứ thứ gì và do đó không có thuộc tính nào cả.
Nói cách khác: Theo mặc định, một đối tượng javascript kế thừa từ Object, trừ khi bạn rõ ràng tạo nó với null làm nguyên mẫu của nó, như : Object.create(null).
{}thay vào đó sẽ tương đương với Object.create(Object.prototype).
Trong Chrome Devtool, bạn có thể thấy rằng Object.create(null)không có thuộc __proto__tính {}.
Chúng chắc chắn không tương đương. Tôi đang viết câu trả lời này để giải thích đầy đủ hơn tại sao nó lại tạo ra sự khác biệt.
var p = {};
Tạo một đối tượng kế thừa các thuộc tính và phương thức từ đó Object.
var p2 = Object.create(null);
Tạo một đối tượng không kế thừa bất cứ thứ gì.
Nếu bạn đang sử dụng một đối tượng làm bản đồ và bạn tạo một đối tượng bằng phương pháp 1 ở trên, thì bạn phải hết sức cẩn thận khi thực hiện tra cứu trên bản đồ. Vì các thuộc tính và phương thức Objectđược kế thừa, mã của bạn có thể gặp trường hợp có các khóa trong bản đồ mà bạn không bao giờ chèn. Ví dụ: nếu bạn đã tra cứu toString, bạn sẽ tìm thấy một hàm, mặc dù bạn không bao giờ đặt giá trị đó ở đó. Bạn có thể làm việc xung quanh như thế này:
if (Object.prototype.hasOwnProperty.call(p, 'toString')) {
// we actually inserted a 'toString' key into p
}
Lưu ý rằng việc gán một cái gì đó là tốt p.toString, nó sẽ đơn giản ghi đè toStringchức năng được kế thừa trên p.
Lưu ý rằng bạn không thể làm p.hasOwnProperty('toString')vì bạn có thể đã chèn khóa "hasOwnProperty" vào p, vì vậy chúng tôi buộc nó phải sử dụng triển khai Object.
Mặt khác, nếu bạn sử dụng phương pháp 2 ở trên, thì bạn sẽ không phải lo lắng về những thứ Objectxuất hiện trên bản đồ.
Bạn không thể kiểm tra sự tồn tại của một tài sản với cách đơn giản ifnhư sau:
// Unreliable:
if (p[someKey]) {
// ...
}
Giá trị có thể là một chuỗi rỗng, có thể false, hoặc null, undefinedhoặc 0, hoặc NaN, v.v. Để kiểm tra xem một thuộc tính có tồn tại hay không, bạn vẫn sẽ cần sử dụng Object.prototype.hasOwnProperty.call(p, someKey).
Object.create(null). Tôi không muốn đưa ra các giả định như vậy, ngay cả khi bạn hoàn toàn đúng khi sử dụng nó Object.create(null), mã có thể thay đổi, đối tượng có thể được thay thế bằng một kế thừa Objecttại một số điểm. hasOwnPropertyluôn luôn làm việc
{}là phổ biến hơn nhiều so với Object.create(null), nếu mã của bạn vô tình lấy một tài sản được thừa kế tại thời điểm này, bạn có thể có những lỗi lớn hơn để lo lắng. Tôi chỉ có thể xem mọi người sử dụng Object.create (null) như một tối ưu hóa nhỏ.
!!p[key]hoạt động tốt với Object.create(null). Nhưng điều đó hasKey = (key, input) => Object.prototype.hasOwnProperty.call(input, key)cũng không tệ
pvì mọi phương thức đều có thể được chèn và do đó trở nên không an toàn.
Tạo các đối tượng bằng cách sử dụng {}sẽ tạo ra một đối tượng có nguyên mẫu Object.prototypekế thừa các chức năng cơ bản từ Objectnguyên mẫu trong khi tạo các đối tượng bằng cách sử dụng Object.create(null)sẽ tạo ra một đối tượng trống có nguyên mẫu là null.
Nếu ai đó đang tìm kiếm để thực hiện Object.create(null), chỉ để biết làm thế nào nó hoạt động. Nó được viết bằng cách sử dụng __proto__không chuẩn và do đó, tôi không khuyên dùng nó .
function objectCreateMimic()
{
/*optional parameters: prototype_object, own_properties*/
var P = arguments.length>0?arguments[0]:-1;
var Q = arguments.length>1?arguments[1]:null;
var o = {};
if(P!==null && typeof P === "object")
{
o.__proto__ = P;
}
else if(P===null)
{
o.__proto__ = null;
}
if(Q!==null && typeof Q === "object")
{
for(var key in Q)
{
o[key] = Q[key];
}
}
return o;
}
Lưu ý : Tôi đã viết điều này, vì tò mò và nó chỉ được viết bằng các thuật ngữ đơn giản, ví dụ, tôi không chuyển các mô tả thuộc tính từ đối tượng thứ hai sang đối tượng trả về.
__proto__giờ đây sẽ chính thức là một phần của ngôn ngữ.
-1trong arguments.length>0?arguments[0]:-1;?
Objectnguyên mẫu được giữ lại nếu đối số đầu tiên không được đưa ra. Tên biến có thể tốt hơn rất nhiều ở đây.
Khi bạn tạo một Object bằng Object.create (null) có nghĩa là bạn đang tạo một Object không có nguyên mẫu. null ở đây có nghĩa là kết thúc chuỗi nguyên mẫu. Tuy nhiên, khi bạn tạo một đối tượng như {} Nguyên mẫu đối tượng sẽ được thêm vào. Do đó đây là hai đối tượng khác nhau, một đối tượng có nguyên mẫu khác không có nguyên mẫu. Hy vọng điều này sẽ giúp
if (someKey in p) {