2016-10-03 3 views
8

У меня есть класс машинописиКлонирование машинописи объекта

export class Restaurant { 

    constructor (private id: string, private name: string) { 

    } 

    public getId() : string { 
    return this.id; 
    } 

    public setId(_id : string) { 
    this.id = _id; 
    } 

    public getName() { 
    return this.name; 
    } 

    public setName (_name:string) { 
    this.name = _name; 
    } 

} 

Я тогда экземпляр этого класса (это пример):

restaurant:Restaurant = new Restaurant(1,"TestRest"); 

Я тогда хранить этот объект ресторана в некотором роде кэш

cache.store(restaurant); 

потом в моем приложении я получаю ресторан назад

var restToEdit = cache.get("1"); 
restToEdit.setName("NewName"); 

Но из-за того, что javascripts проходят по ссылке на объекты, изменения, которые я делаю для restToEdit, также сохраняются в ресторане, который находится в кеше.

В основном я хочу, чтобы ресторан в кеше был совершенно другим экземпляром для restToEdit.

Я пробовал использовать jQuery.clone и расширять, но, похоже, это не работает, и я думаю, что это из-за того, что он является объектом машинописного текста. Или это не имеет значения?

Любые ответы о том, как клонировать этот объект был бы оценен

Благодаря

ответ

1

.clone() только клоны DOM элементов. Чтобы клонировать объекты JavaScript, попробуйте jQuery.extend. Что-то вроде этого

// Shallow copy 
var newObject = jQuery.extend({}, oldObject); 

// Deep copy 
var newObject = jQuery.extend(true, {}, oldObject); 

Тип машинописных текстов переводится на JavaScript. Таким образом, JavaScript-метод будет работать нормально.

Демонстрация:

// Transpiled version of TypeScript 
 
"use strict"; 
 
    var Restaurant = (function() { 
 
     function Restaurant(id, name) { 
 
      this.id = id; 
 
      this.name = name; 
 
     } 
 
     Restaurant.prototype.getId = function() { 
 
      return this.id; 
 
     }; 
 
     Restaurant.prototype.setId = function (_id) { 
 
      this.id = _id; 
 
     }; 
 
     Restaurant.prototype.getName = function() { 
 
      return this.name; 
 
     }; 
 
     Restaurant.prototype.setName = function (_name) { 
 
      this.name = _name; 
 
     }; 
 
     return Restaurant; 
 
    }()); 
 

 
// Test Snippet 
 
var r1 = new Restaurant(1, "A"); 
 
var r2 = jQuery.extend(true, {}, r1); 
 

 
r2.setName("B"); 
 

 
console.log(r1.name); 
 
console.log(r2.name);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

+0

Спасибо, это работает. Просто не чувствовал себя хорошо в отношении машинописных текстов. Мне не нравится использовать Javascript-код в машинописном тексте только потому, что я знаю, что он будет работать. Но пока это похоже на единственное решение. Спасибо – mwild

+0

Вы можете обернуть его на класс/прототип: 'public clone(): Restaurant {/ * тот же код jquery, просто верните r2 * /}' – cdbajorin

12
  • Использование стандартного ES6 features

    const clone = Object.assign({}, myObject) 
    

    Внимание: это выполняет мелкий клон.

    Это excellent page from MDN содержит тонны деталей по клонированию, в том числе polyfill для ES5

  • А «быстрый» способ глубокого клонирования заключается в использовании JSON утилиты

    const clone = JSON.parse(JSON.stringify(myObject)) 
    
  • А «правильный» способ клонирование - реализовать метод клонирования или конструктор копирования ...

Я знаю, я знаю, not enough JQuery

+1

'Object.assign' копии со ссылкой. – Thaadikkaaran

+2

Использование Json.parse, а затем Json.stringify теряет функции, назначенные объекту – mwild

+0

@JaganathanBantheswaran ... это прекрасно, если ваше мелкое клонирование или клонирование неизменяемых свойств! –

4

Это, кажется, работает для меня:

var newObject = Object.assign(Object.create(oldObj), oldObj) 

Object.create создает новый экземпляр с пустыми свойствами Object.assign затем принимает этот новый экземпляр и присваивает свойства

Более надежная версия функции клонирования

clone(obj) { 
     if(Array.isArray(obj)) { 
      return Array.from(obj); 
     } else { 
      return Object.assign(Object.create(obj), obj); 
     } 
    } 
+2

Только мелкий клон. Любые ссылки по-прежнему указывают на исходный объект. – etech

+0

Я бы предложил использовать 'Object.create (Object.getPrototypeOf (obj))' вместо 'Object.create (obj)'. Текущий код имеет следующую проблему: если 'obj' имеет свойство, которое было' undefined' во время копирования, то после изменения этого свойства на некоторое значение в исходном 'obj', клон увидит изменение. – user3707125

3

Если вы используете TS 2.1, вы можете использовать оператор объекта распространения, чтобы создать неполную копию:

const obj = { a: 1 }; 
const clonedObj = { ...obj };