2013-10-31 19 views
13

Ví dụ này tạo đối tượng, đóng băng đối tượng đó và sau đó tạo đối tượng mới từ đối tượng được cố định. Nếu đối tượng thứ hai cố gắng thay đổi thuộc tính thử nghiệm, nó không thể. Nó vẫn còn đông lạnh với giá trị đầu tiên đối tượng của 10.Tạo đối tượng mới từ đối tượng gốc được cố định

//Create an object and freeze it 

var first = { 
    test: 10 
}; 
Object.freeze(first); 

//Create a second object from the first one and 
//try and change the new test property (you can't) 

var second = Object.create(first); 
second.test = 20; 
console.log(second.test); //10 

Dưới đây là những câu hỏi của tôi:

second.test một tài sản mới trên một đối tượng mới, hoặc là nó chỉ là một tham chiếu đến bất động sản trong đông lạnh đối tượng đầu tiên?
Có thể sử dụng giá trị mặc định là first.test, nhưng để second.test ghi đè lên nếu cần?

Lý do yêu cầu của tôi là vì tôi muốn tạo một đối tượng cơ bản không thay đổi làm mẫu có giá trị mặc định và sau đó sử dụng nó để tạo đối tượng mới mà tôi có thể tùy chỉnh. Cách tiếp cận tốt nhất cho việc này là gì?

Cảm ơn!

Trả lời

11

second thực tế là một đối tượng mới, với first là nguyên mẫu của second. Lý do tại sao

second.test = 20; 

không hoạt động là bởi vì khi chuyển nhượng, nó sẽ tìm kiếm các thiết lập trên nguyên mẫu (tức là configurable, enumerable, writable, [[Extensible]]) và không gán cho các trường hợp nếu có trong số này là sai . Để gán trực tiếp cho các trường hợp, bạn sẽ phải sử dụng Object.defineProperty trên second:

var first = { 
    test: 10 
}; 
Object.freeze(first); 

var second = Object.create(first); 
Object.defineProperty(second, 'test', { value: 20, enumerable: true, configurable: true, writable: true }); 
console.log(second.test); // 20 

1:[[Put]]: the ECMAScript Specification, §8.12.5

2

Trong trường hợp của bạn second là một tham chiếu đến first (như bạn giả định). Một giải pháp sẽ là sao chép đối tượng của bạn. Không có build theo cách sao chép các đối tượng - bạn phải làm điều đó cho mình, đây là cách (source):

function clone(obj){ 
    if(obj == null || typeof(obj) != 'object') 
     return obj; 

    var temp = obj.constructor(); 

    for(var key in obj) 
     temp[key] = clone(obj[key]); 
    return temp; 
} 

Sau đó, bạn sử dụng nó theo cách này:

var first = { 
    test: 10 
}; 
Object.freeze(first); 

// clone it into a new one 
var second = clone(first); 
second.test = 20; 
console.log(second.test); // 20 where the first is locked 
6

Sử dụng Object.assign

  var first = { 
      test: 10 
     }; 
     Object.freeze(first); 

     //Create a second object from the first one and 
     //try and change the new test property (you can't) 

     var second = Object.assign({}, first, { 
      test: 20 
     }); 
     console.log(second.test); //20 
+0

Trường hợp khá bên ngoài, nhưng lưu ý rằng điều này vẫn không hoạt động nếu đối tượng cố định chứa tham chiếu đến các đối tượng được cố định khác và bạn cố ghi đè thuộc tính _their_. Vẫn là một kỹ thuật khá hữu ích cho các cấu trúc dữ liệu đơn giản, chỉ không ai có được ý tưởng rằng đó là một cách dễ dàng để tạo ra bất biến. – Dtipson

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